Conflux js-sdk與以太坊web3. js區別

Conflux中文社群發表於2021-12-23

Web3.js vs js-conflux-sdk

js-conflux-sdk 最新版本為1.x, 與0.x有很大差別, 但由於其還在測試階段,本文只對0.13.4Web3進行對照,待1.x版本穩定後, 再針對1.x與Web3進行對照。

Web3js-conflux-sdk 都是最頂層模組,他們包含了其它子模組以及在頂層暴露了一些子模組中的方法方便開發者快捷使用,我們這裡只比較各模組,而不再對這些快捷方法做特別說明。

模組對比

Web3js-conflux-sdk 有對應關係的主要有以下模組:

Ethereum中的模組Conflux中的模組功能
EthConflux用於管理連線節點,與節點互動,傳送rpc請求,包含讀取狀態、傳送交易等
Contract + abiContract用於操作智慧合約,包含建立合約例項、調動合約方法,以及提供一些根據abi編解碼的功能
accountsaccount + Message + Transaction用於管理賬戶,包含建立、刪除賬戶,及使用賬戶對訊息或交易進行簽名等操作
utilsutil工具類,提供一些通用函式,例如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
setProvidersetProvider-
getStatusgetChainIdcfx_getStatus
getGasPricegetGasPricecfx_gasPrice
getEpochNumbergetBlockNumbercfx_epochNumber
getBalancegetBalancecfx_getBalance
getNextNoncegetBlockTransactionCountcfx_getNextNonce
getBlockByEpochNumbergetBlockcfx_getBlockByEpochNumber
getBlocksByEpochNumber-cfx_getBlocksByEpoch
getBlockByHashgetBlockcfx_getBlockByHash
getBlockByHashWithPivotAssumption-cfx_getBlockByHashWithPivotAssumption
getTransactionByHashgetTransactioncfx_getTransactionByHash
getTransactionReceiptgetTransactionReceiptcfx_getTransactionReceipt
sendTransactionsendTransactioncfx_sendTransaction
sendRawTransactionsendSignedTransactioncfx_sendRawTransaction
getCodegetCodecfx_getCode
callcallcfx_call
estimateGasAndCollateralestimateGascfx_estimateGasAndCollateral
getLogsgetPastLogs(contract模組)cfx_getLogs
getBestBlockHash-cfx_getBestBlockHash
getConfirmationRiskByHash-cfx_getConfirmationRiskByHash
close--

Contract 模組對比

Conflux Contract 模組Eth Contract + abi 模組
contract.mymethodmethods.myMethod.call
contract.mymethod.callmethods.myMethod.call
contract.mymethod.decodeDatadecodeParameters
contract.mymethod.decodeOutputs-
contract.mymethod.encodeDatamethods.myMethod.encodeABI
contract.mymethod.sendmethods.myMethod.send
contract.mymethod.estimateGasAndCollateralmethods.myMethod.estimateGas
contract.myEvent.getLogsgetPastLogs
contract.myEvent.encodeTopics-
contract.myEvent.decodeLogdecodeLog(ABI模組)
contract.abi.decodeDatadecodeParameters
contract.abi.decodeLogdecodeLog(ABI模組)

accounts 模組對比

Conflux Account模組Ethereum Accounts模組
randomcreate
decryptdecrypt
encryptencrypt
signTransactionsignTransaction
signMessagesign
Conflux Message模組Ethereum Accounts模組
signsign
recoverrecover
hash (getter)-
from (getter)-
signsign
Conflux Transaction模組Ethereum Accounts模組
hash (getter)-
from (getter)-
signsignTransaction
recoverrecover
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)-
sha3sha3
checksumAddresstoChecksumAddress
randomBuffer-
randomPrivateKeyrandomHex
privateKeyToPublicKeyprivateKeyToAccount(Accounts模組)
publicKeyToAddressprivateKeyToAccount(Accounts模組)
privateKeyToAddressprivateKeyToAccount(Accounts模組)
ecdsaSignsign(Accounts模組)
ecdsaRecoverrecover(Accounts模組)
encryptencrypt(Accounts模組)
decryptdecrypt(Accounts模組)
unit.fromCFXToGDrip-
unit.fromCFXToDriptoWei
unit.fromGDripToCFX-
unit.fromGDripToDrip-
unit.fromDripToCFXfromWei
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

也可以通過該物件方法在不同狀態下返回transactiontransaction receipt, 方法列舉如下:

  • get在傳送完成後返回transaction,
  • mined在打包完成後返回transaction,
  • executed在執行完成後返回transaction receipt,
  • confirmedtransaction 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使用數量和儲存抵押數量;然而由於實際執行消耗與預估結果有差異,為了防止交易執行失敗,建議在實際傳送交易時,設定gaslimitstorage_limit的值為預估值 * 4/3

引數EpochHeight表示這筆交易將會在 Epoch[EpochHeight-100000 , EpochHeight+100000] 的區間內執行,當超出這個區間這筆交易將被丟棄,建議設定當前Epoch值即可。

部署合約

部署合約實質就是傳送一筆data為合約bytecodetonull的交易

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 receiptcontractCreated欄位就是部署後的合約地址。注意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(基本銀行賬號)地址格式的轉換

文章引用

  1. js-conflux-sdk 使用者手冊
  2. Web3 v1.2.11 使用者手冊
  3. Conflux JSONRPC介紹
  4. Conflux RPC與Ethereum RPC的區別

相關文章