Web3.js vs js-conflux-sdk
js-conflux-sdk
最新版本為1.x
, 與0.x
有很大差別, 但由於其還在測試階段,本文只對0.13.4
與Web3
進行對照,待1.x
版本穩定後, 再針對1.x
與Web3進行對照。
Web3
和 js-conflux-sdk
都是最頂層模組,他們包含了其它子模組以及在頂層暴露了一些子模組中的方法方便開發者快捷使用,我們這裡只比較各模組,而不再對這些快捷方法做特別說明。
模組對比
Web3
和 js-conflux-sdk
有對應關係的主要有以下模組:
Ethereum中的模組 | Conflux中的模組 | 功能 |
---|---|---|
Eth | Conflux | 用於管理連線節點,與節點互動,傳送rpc請求,包含讀取狀態、傳送交易等 |
Contract + abi | Contract | 用於操作智慧合約,包含建立合約例項、調動合約方法,以及提供一些根據abi編解碼的功能 |
accounts | account + Message + Transaction | 用於管理賬戶,包含建立、刪除賬戶,及使用賬戶對訊息或交易進行簽名等操作 |
utils | util | 工具類,提供一些通用函式,例如hex格式轉換,單位轉換,私鑰轉公鑰及地址,生成隨機私鑰,判斷資料型別,sha3等,方便dapp開發及其他js包使用 |
各模組方法對比
Conflux模組 Vs Eth模組
以下是Conflux模組包含的方法及與Eth模組的對應關係,該模組主要封裝了JSONRPC與節點互動,還有一部分JSONRPC暫未實現,將來會不斷完善RPC。。具體RPC介紹請參見 Conflux JSONRPC介紹 及 [Conflux RPC與Ethereum RPC的區別]()
這裡的Epoch Number指用於劃分一組Conflux區塊為一個Epoch,Conflux區塊鏈是以Epoch為順序組織的。
Conflux模組 | Ethereum Eth模組 | 對應RPC |
---|---|---|
setProvider | setProvider | - |
getStatus | getChainId | cfx_getStatus |
getGasPrice | getGasPrice | cfx_gasPrice |
getEpochNumber | getBlockNumber | cfx_epochNumber |
getBalance | getBalance | cfx_getBalance |
getNextNonce | getBlockTransactionCount | cfx_getNextNonce |
getBlockByEpochNumber | getBlock | cfx_getBlockByEpochNumber |
getBlocksByEpochNumber | - | cfx_getBlocksByEpoch |
getBlockByHash | getBlock | cfx_getBlockByHash |
getBlockByHashWithPivotAssumption | - | cfx_getBlockByHashWithPivotAssumption |
getTransactionByHash | getTransaction | cfx_getTransactionByHash |
getTransactionReceipt | getTransactionReceipt | cfx_getTransactionReceipt |
sendTransaction | sendTransaction | cfx_sendTransaction |
sendRawTransaction | sendSignedTransaction | cfx_sendRawTransaction |
getCode | getCode | cfx_getCode |
call | call | cfx_call |
estimateGasAndCollateral | estimateGas | cfx_estimateGasAndCollateral |
getLogs | getPastLogs(contract模組) | cfx_getLogs |
getBestBlockHash | - | cfx_getBestBlockHash |
getConfirmationRiskByHash | - | cfx_getConfirmationRiskByHash |
close | - | - |
Contract 模組對比
Conflux Contract 模組 | Eth Contract + abi 模組 |
---|---|
contract.mymethod | methods.myMethod.call |
contract.mymethod.call | methods.myMethod.call |
contract.mymethod.decodeData | decodeParameters |
contract.mymethod.decodeOutputs | - |
contract.mymethod.encodeData | methods.myMethod.encodeABI |
contract.mymethod.send | methods.myMethod.send |
contract.mymethod.estimateGasAndCollateral | methods.myMethod.estimateGas |
contract.myEvent.getLogs | getPastLogs |
contract.myEvent.encodeTopics | - |
contract.myEvent.decodeLog | decodeLog(ABI模組) |
contract.abi.decodeData | decodeParameters |
contract.abi.decodeLog | decodeLog(ABI模組) |
accounts 模組對比
Conflux Account模組 | Ethereum Accounts模組 |
---|---|
random | create |
decrypt | decrypt |
encrypt | encrypt |
signTransaction | signTransaction |
signMessage | sign |
Conflux Message模組 | Ethereum Accounts模組 |
---|---|
sign | sign |
recover | recover |
hash (getter) | - |
from (getter) | - |
sign | sign |
Conflux Transaction模組 | Ethereum Accounts模組 |
---|---|
hash (getter) | - |
from (getter) | - |
sign | signTransaction |
recover | recover |
encode | - |
serialize | - |
utils 模組對比
Conflux util 模組 | Ethereum utils模組 |
---|---|
format.any (setter) | - |
format.hex (setter) | toHex, numberToHex |
format.uInt (setter) | - |
format.bigInt (setter) | toBN |
format.bigUInt (setter) | - |
format.hexUInt (setter) | - |
format.riskNumber (setter) | - |
format.epochNumber (setter) | - |
format.address (setter) | bytesToHex |
format.publicKey (setter) | bytesToHex |
format.privateKey (setter) | bytesToHex |
format.signature (setter) | bytesToHex |
format.blockHash (setter) | bytesToHex |
format.txHash (setter) | bytesToHex |
format.buffer (setter) | toHex + hexToBytes |
format.boolean (setter) | - |
sha3 | sha3 |
checksumAddress | toChecksumAddress |
randomBuffer | - |
randomPrivateKey | randomHex |
privateKeyToPublicKey | privateKeyToAccount(Accounts模組) |
publicKeyToAddress | privateKeyToAccount(Accounts模組) |
privateKeyToAddress | privateKeyToAccount(Accounts模組) |
ecdsaSign | sign(Accounts模組) |
ecdsaRecover | recover(Accounts模組) |
encrypt | encrypt(Accounts模組) |
decrypt | decrypt(Accounts模組) |
unit.fromCFXToGDrip | - |
unit.fromCFXToDrip | toWei |
unit.fromGDripToCFX | - |
unit.fromGDripToDrip | - |
unit.fromDripToCFX | fromWei |
unit.fromDripToGDrip | - |
使用對比
初始化
初始化Web3例項
var Web3 = require('web3');
// "Web3.providers.givenProvider" will be set if in an Ethereum supported browser.
var web3 = new Web3(Web3.givenProvider || 'ws://some.local-or-remote.node:8546');
// or
var web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
初始化Conflux例項
Conflux例項化與web3類似,但當前版本還不支援 webscoket provider
const { Conflux } = require('js-conflux-sdk');
const cfx = new Conflux({url:'http://test.confluxrpc.org'});
讀狀態
Ethereum讀狀態
web3.eth.getBalance("0x107d73d8a49eeb85d32cf465507dd71d507100c1").then(console.log);
> "1000000000000"
Conflux讀狀態
await cfx.getBalance("0x107d73d8a49eeb85d32cf465507dd71d507100c1");
// or
cfx.getBalance("0x107d73d8a49eeb85d32cf465507dd71d507100c1").then(console.log)
> "1000000000000"
傳送交易
web3 傳送交易
web3傳送交易後通過event
方式在以下各個階段達成時通知:
transactionHash
交易已傳送receipt
交易已執行confirmation
交易已確認error
交易執行失敗
// compiled solidity source code using <https://remix.ethereum.org>
var code = "603d80600c6000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463c6888fa18114602d57005b6007600435028060005260206000f3";
// using the callback
web3.eth.sendTransaction({
from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe',
data: code // deploying a contracrt
}, function(error, hash){
...
});
// using the promise
web3.eth.sendTransaction({
from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe',
to: '0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe',
value: '1000000000000000'
})
.then(function(receipt){
...
});
// using the event emitter
web3.eth.sendTransaction({
from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe',
to: '0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe',
value: '1000000000000000'
})
.on('transactionHash', function(hash){
...
})
.on('receipt', function(receipt){
...
})
.on('confirmation', function(confirmationNumber, receipt){ ... })
.on('error', console.error); // If a out of gas error, the second parameter is the receipt.
Conflux傳送交易
js-conflux-sdk 由於當前版本沒有增加訪問節點本地錢包功能,所以傳送交易時需要直接指定Account
; sendTransaction
返回的是一個 Promise.<PendingTransaction>
物件, 可以直接await
獲取transaction hash
;
也可以通過該物件方法在不同狀態下返回transaction
或transaction receipt
, 方法列舉如下:
get
在傳送完成後返回transaction
,mined
在打包完成後返回transaction
,executed
在執行完成後返回transaction receipt
,confirmed
在transaction risk < threshold
時返回transaction receipt
const account = cfx.Account(your_private_key);
const promise = cfx.sendTransaction({ // Not await here, just get promise
from: account,
to: "0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe",
value: Drip.fromCFX(0.007),
});
> await promise; // transaction
"0x91fbdfb33f3a585f932c627abbe268c7e3aedffc1633f9338f9779c64702c688"
> await promise.get(); // get transaction
{
"blockHash": null,
"transactionIndex": null,
"hash": "0x91fbdfb33f3a585f932c627abbe268c7e3aedffc1633f9338f9779c64702c688",
...
}
> await promise.mined(); // wait till transaction mined
{
"blockHash": "0xe9b22ce311003e26c7330ac54eea9f8afea0ffcd4905828f27c9e2c02f3a00f7",
"transactionIndex": 0,
"hash": "0x91fbdfb33f3a585f932c627abbe268c7e3aedffc1633f9338f9779c64702c688",
...
}
> await promise.executed(); // wait till transaction executed in right status. and return it's receipt.
{
"blockHash": "0xe9b22ce311003e26c7330ac54eea9f8afea0ffcd4905828f27c9e2c02f3a00f7",
"index": 0,
"transactionHash": "0x91fbdfb33f3a585f932c627abbe268c7e3aedffc1633f9338f9779c64702c688",
"outcomeStatus": 0,
...
}
> await promise.confirmed(); // wait till transaction risk coefficient '<' threshold.
{
"blockHash": "0xe9b22ce311003e26c7330ac54eea9f8afea0ffcd4905828f27c9e2c02f3a00f7",
"index": 0,
"transactionHash": "0x91fbdfb33f3a585f932c627abbe268c7e3aedffc1633f9338f9779c64702c688",
"outcomeStatus": 0,
...
}
需要注意的地方:
傳送交易時,建議先使用 estimateGasAndCollateral
返回預估的gas使用數量和儲存抵押數量;然而由於實際執行消耗與預估結果有差異,為了防止交易執行失敗,建議在實際傳送交易時,設定gaslimit
與storage_limit
的值為預估值 * 4/3
。
引數EpochHeight表示這筆交易將會在 Epoch
為 [EpochHeight-100000 , EpochHeight+100000]
的區間內執行,當超出這個區間這筆交易將被丟棄,建議設定當前Epoch值即可。
部署合約
部署合約實質就是傳送一筆data
為合約bytecode
,to
為null
的交易
web3部署合約
web3可以通過直接傳送交易的方式部署,也可以通過contract例項部署
// send transaction directly
await web3.eth.sendTransaction({
from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe',
data: contract_bytecode,
})
> {
"status": true,
"contractAddress": "0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe",
...
}
// or use contract instance
var myContract = new web3.eth.Contract(contract_abi, '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe', {
from: '0x1234567890123456789012345678901234567891', // default from address
...
});
myContract.deploy({
data: '0x12345...',
arguments: [123, 'My String']
})
.send({
from: '0x1234567890123456789012345678901234567891',
gas: 1500000,
gasPrice: '30000000000000'
}, function(error, transactionHash){ ... })
.on('error', function(error){ ... })
.on('transactionHash', function(transactionHash){ ... })
.on('receipt', function(receipt){
console.log(receipt.contractAddress) // contains the new contract address
})
.on('confirmation', function(confirmationNumber, receipt){ ... })
.then(function(newContractInstance){
console.log(newContractInstance.options.address) // instance with the new contract address
});
conflux部署合約
conflux當前只能通過傳送交易的方式部署,transaction receipt
的contractCreated
欄位就是部署後的合約地址。注意contract_bytecode資料需要0x開頭的資料。
const account = cfx.Account(your_private_key);
await cfx.sendTransaction({ // Not await here, just get promise
from: account,
data: contract_bytecode,
}).executed();
> {
"outcomeStatus": 0,
"contractCreated": "0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe",
...
}
呼叫合約
呼叫合約分兩種:
- 一種是讀狀態,不需要傳送交易,讀狀態web3跟conflux都使用call方法。
- 一種是修改合約狀態,需要傳送交易,修改合約狀態web3使用
send
,conflux
使用sendTransaction
web3呼叫合約
// create contract instance
var myContract = new web3.eth.Contract(contract_abi, contract_address);
// calling a method
myContract.methods.myMethod(123).call({from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'}, function(error, result){
...
});
// or sending and using a promise
myContract.methods.myMethod(123).send({from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'})
.then(function(receipt){
// receipt can also be a new contract instance, when coming from a "contract.deploy({...}).send()"
...
});
conflux呼叫合約
conflux 呼叫合約與web3類似,需要注意的地方是呼叫合約傳送交易前建議根據estimateGasAndCollateral得到的gasUsed與storageCollateralized計算gas(同以太坊的gasLimit)與storageLimit; 由於實際執行交易時使用的gas與storageCollateralized與預估可能會有差別,為了防止失敗,建議設定 gas = estimated.gasUsed * 4 / 3
,storageLimit = estimated.storageCollateralized * 4 /3
// create contract instance
var myContract = cfx.Contract({
abi: contract_abi,
address: contract_address
});
// call
await contract.myCallMethod(123)
await contract.myCallMethod().call(123)
// send
// set gasLimit and sotrageLimit large 1/3 than estimated value
const estimated = await contract.mySendMethod(123).estimateGasAndCollateral({from: '0x1e0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'});
let gasLimit = JSBI.multiply(estimated.gasUsed, JSBI.BigInt(4))
gasLimit = JSBI.divide(gasLimit, JSBI.BigInt(3))
let storageLimit = JSBI.multiply(estimated.storageCollateralized, JSBI.BigInt(4))
storageLimit = JSBI.divide(storageLimit, JSBI.BigInt(3))
// send transaction
await contract.mySendMethod(123).sendTransaction({from: "addres",gasLimit:estimated.gas*4/3}).executed();
eth 中的其它模組
除了以上介紹的模組,web3中還包含了以下模組;這些模組conflux中暫時還沒有對應模組,將來可能支援類似功能
web3模組 | 作用 |
---|---|
personal | 使用所請求節點的賬戶進行簽名、鎖定、解鎖等操作 |
shh | 用於使用whisper協議傳播訊息 |
bzz | 用於與swarm互動,swarm是一個分散式檔案儲存系統 |
net | 獲取節點資訊 |
subscribe | 訂閱鏈上產生的新時間,包含logs ,pendingTransactions ,newBlockHeaders .syncing 等 |
ens | 用於操作以太坊的域名服務 |
Iban | 以太坊地址格式與IBAN(國際銀行帳號) BBAN(基本銀行賬號) 地址格式的轉換 |