2019-07-04 ewasm在以太坊私有鏈測試(3)

ewasm由于變化比較大,導致文章2018-11-26 ewasm在以太坊私有鏈測試
2019-03-15 ewasm在以太坊私有鏈測試(2)已經無法成功發(fā)布和調用合約了,參考文章initial version of wrc20 token修改得到以下方法:

1、發(fā)布合約

先拉取代碼,并按readme的方法操作

git clone https://github.com/hugo-dc/deploy-ewasm

cargo install chisel
cd deploy-ewasm\example
chisel run

能夠獲取store_deployer.wasm文件,然后執(zhí)行:

cd ..
./sendtx.sh ./example/store_deployer.wasm 9 '8DFFB7687E432CF9540728F41579452F2F9B646DD29BBCA57B1AFE76817EC379'
Generating transaction...
Sending transaction...
0xf9012d09843b9aca00830f42408080b8dc0061736d0100000001090260027f7f0060000002130108657468657265756d0666696e697368000003030200010503010001071102046d61696e0002066d656d6f727902000a0e0202000b0900410041fe0010000b0b8401010041000b7e0061736d0100000001090260027f7f0060000002190108657468657265756d0c73746f7261676553746f72650000030201010503010001071102066d656d6f72790200046d61696e00010a0a0108004100412010000b0b26010041200b2000000000000000000000000000000000000000000000000000000000000000011ba055e580e1cdd74e63edac6114055b9293e2c2d32b1073e079152f6e9a69df039ea068fb6f81cce137032af8c716154866bc75b4b2b166ffacdd9c08a26f8f89b973
{"jsonrpc":"2.0","id":2,"error":{"code":-32000,"message":"intrinsic gas too low"}}

注:參數說明,參數9是nonce值,參數'8DFFB7687E432CF9540728F41579452F2F9B646DD29BBCA57B1AFE76817EC379'是當前發(fā)送交易的賬戶的私鑰
出現了錯誤信息,"intrinsic gas too low"
修改文件txn.js
修改了txParams.gasLimit = gas
為:txParams.gasLimit = 1000000
再次執(zhí)行:

./sendtx.sh ./example/store_deployer.wasm 9 '8DFFB7687E432CF9540728F41579452F2F9B646DD29BBCA57B1AFE76817EC379'
Generating transaction...
Sending transaction...
0xf9012d09843b9aca00830f42408080b8dc0061736d0100000001090260027f7f0060000002130108657468657265756d0666696e697368000003030200010503010001071102046d61696e0002066d656d6f727902000a0e0202000b0900410041fe0010000b0b8401010041000b7e0061736d0100000001090260027f7f0060000002190108657468657265756d0c73746f7261676553746f72650000030201010503010001071102066d656d6f72790200046d61696e00010a0a0108004100412010000b0b26010041200b2000000000000000000000000000000000000000000000000000000000000000011ba055e580e1cdd74e63edac6114055b9293e2c2d32b1073e079152f6e9a69df039ea068fb6f81cce137032af8c716154866bc75b4b2b166ffacdd9c08a26f8f89b973
{"jsonrpc":"2.0","id":2,"result":"0xda7a8778c5c2af8898a04995c200a347c2e000e985613b1c60e92c2accf6be88"}

這次成功了,查詢交易0xda7a8778c5c2af8898a04995c200a347c2e000e985613b1c60e92c2accf6be88
可能還處于pending狀態(tài),需要等一段時間,這個網站好慢,然后可以看到| To: | New Contract (deployment address:0x7E729E5353C8AE3eD3Fe5669Ccd771A613acB17b) |
打開上面的連接,可以看到當前合約的wast代碼,storage為空

2、調用合約

需要自己寫個腳本和js
文件calltx.sh

#!/bin/bash

echo Generating transaction...
tx=$(node calltxn.js --nonce $1 --priv $2 --to $3)

echo Sending transaction...
echo $tx
curl -X POST -H 'Content-Type: application/json' --data "{\"jsonrpc\":\"2.0\",\"method\":\"eth_sendRawTransaction\",\"params\":[\"$tx\"],\"id\":2}" http://ewasm.ethereum.org:8545

文件calltxn.js

const EthereumTx = require('ethereumjs-tx')
var Web3 = require('web3')

var web3Provider = new Web3.providers.HttpProvider('http://ewasm.ethereum.org:8545')
var web3 = new Web3(web3Provider)

const argv = require('yargs').argv;
const fs = require('fs')
const request = require('request')

let data = ''
let nonce = argv.nonce ? argv.nonce : ''
let to = argv.to ? argv.to : ''

let priv = argv.priv

const privateKey = Buffer.from(priv, 'hex')


var txParams = {}

txParams.data = data
txParams.value = '0x0'
txParams.nonce = nonce
txParams.to = to

var gasPrice = 1000000000 // web3.eth.gasPrice

web3.eth.estimateGas(txParams, function(err, gas) {

  txParams.gasLimit = 1000000
  txParams.gasPrice = gasPrice

  let tx = new EthereumTx(txParams)
  tx.sign(privateKey)
  let serializedTx = tx.serialize()
  serializedTx = serializedTx.toString('hex')

  console.log("0x"+serializedTx)

})


執(zhí)行:

./calltx.sh 10 '8DFFB7687E432CF9540728F41579452F2F9B646DD29BBCA57B1AFE76817EC379' '0x7E729E5353C8AE3eD3Fe5669Ccd771A613acB17b'

注:參數說明:10是nonce,'8DFFB7687E432CF9540728F41579452F2F9B646DD29BBCA57B1AFE76817EC379' 是私鑰,'0x7E729E5353C8AE3eD3Fe5669Ccd771A613acB17b'是合約地址
成功后查詢交易0x9f6c8aed86b64c3a021685bfedc18a767dbd32a134cc4ddfd5649171234d5688

查詢合約存儲0x7E729E5353C8AE3eD3Fe5669Ccd771A613acB17b
可以看到storage中已經存儲有值:

[
  {
    "key": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "value": "0x0000000000000000000000000000000000000000000000000000000000000001"
  }
]

3、使用自己的私有鏈測試

參考文章2018-11-26 ewasm在以太坊私有鏈測試啟動私有鏈
修改sendtx.sh、txn.js、calltx.sh、calltxn.js中

http://ewasm.ethereum.org:8545

http://localhost:8545

啟動go ethereum

./geth \
--vm.ewasm="./libhera.so,metering=true,fallback=true" \
--datadir ewasm-testnet-data \
--rpc --rpcapi "web3,net,eth,debug" \
--rpcvhosts="*" --rpcaddr "0.0.0.0" \
--rpccorsdomain "*" \
--nodiscover \
--networkid 66 \
--ipcpath geth1.ipc console

獲取當前賬戶的私鑰,參考2018-12-14 查看以太坊私鑰
得到,
然后執(zhí)行發(fā)布腳本:

./sendtx.sh ./example/store_deployer.wasm 1 '63fe0326d54575e4546bad24eb32776fcae08edbf9256b75ee7fcfed2b7d9822'

出現錯誤

{"jsonrpc":"2.0","id":2,"error":{"code":-32000,"message":"nonce too low"}}

在geth下查詢當前nonce


eth.getTransactionCount('0xb338d763691dcfcff4720bc8f3e627901e239b30')

返回10

./sendtx.sh ./example/store_deployer.wasm 10 '63fe0326d54575e4546bad24eb32776fcae08edbf9256b75ee7fcfed2b7d9822'

返回正確:

{"jsonrpc":"2.0","id":2,"result":"0xff31a32577a67ff019ec686e245167adc39de8c18a85afd1f9131db49bcc7afa"}

開始挖礦

miner.start(1);admin.sleepBlocks(1);miner.stop();

在geth中查詢

eth.getTransactionReceipt("0xff31a32577a67ff019ec686e245167adc39de8c18a85afd1f9131db49bcc7afa")

查詢不到,但是日志信息中:

INFO [07-05|10:24:12.521] Submitted contract creation              fullhash=0xff31a32577a67ff019ec686e245167adc39de8c18a85afd1f9131db49bcc7afa contract=0x9e14cE0f3B9AE6006E9E9039E336DB6196Ecb422

我們查詢一下合約:
eth.getCode("0x9e14cE0f3B9AE6006E9E9039E336DB6196Ecb422")
也查詢不到,
eth.getTransaction('0xff31a32577a67ff019ec686e245167adc39de8c18a85afd1f9131db49bcc7afa')
還在,使用

txpool.status
返回:
{
  pending: 1,
  queued: 0
}

發(fā)現還需要挖礦,繼續(xù)

miner.start(1);admin.sleepBlocks(1);miner.stop();

這次總是可以查詢到了,結論是必須挖礦兩次,而不是一次

4、私有鏈下使用rpc測試

操作參考2019-03-14 通過rpc發(fā)布和調用以太坊合約
創(chuàng)建合約

{
    "jsonrpc": "2.0",
    "id": 171,
    "method": "eth_sendTransaction",
    "params": [
        {
            "data": "0x0061736d0100000001090260027f7f0060000002130108657468657265756d0666696e697368000003030200010503010001071102046d61696e0002066d656d6f727902000a0e0202000b0900410041fe0010000b0b8401010041000b7e0061736d0100000001090260027f7f0060000002190108657468657265756d0c73746f7261676553746f72650000030201010503010001071102066d656d6f72790200046d61696e00010a0a0108004100412010000b0b26010041200b200000000000000000000000000000000000000000000000000000000000000001",
            "from": "0xb338d763691dcfcff4720bc8f3e627901e239b30",
            "gas": "0x47b760"
        }
    ]
}

獲得結果

{
    "jsonrpc": "2.0",
    "id": 171,
    "result": "0xcce335377ff76cfa135c88fbc6b337539f03e7808f77473095a670104c3c8929"
}

如果出現"authentication needed: password or unlock",需要解鎖

personal.unlockAccount("0xb338d763691dcfcff4720bc8f3e627901e239b30")

上面data中的數據可以通過wasm2hex.js獲取,其內容

var fs=require('fs');
var path=require('path');

var args = process.argv.splice(2)

var file=path.resolve(args[0]);
var content=Buffer.alloc(0);//累計合并讀取片段
fs.readFile(file,function(err,chunk){
    if(err)
        return console.error(err);
    console.log(chunk);
    //將數據轉換為hex字符串
    console.log(chunk.toString('hex'));
    //合并Buffer
    content=Buffer.concat([content,chunk]);
 
    //保存成文件
     var imgData=Buffer.from(content);
     fs.writeFile(path.resolve('test.txt'),imgData.toString('hex'),function(err){
        if(err)
            return console.error(err);
     });
});

執(zhí)行:

node wasm2hex.js store_deployer.wasm

從生成的文件test.txt復制,記得data前綴是0x,否則出現錯誤:"invalid argument 0: json: cannot unmarshal hex string without 0x prefix into Go struct field SendTxArgs.data of type hexutil.Bytes"
同樣的問題,我們需要挖礦兩次,才能正確獲得交易結果

miner.start(1);admin.sleepBlocks(1);miner.stop();
miner.start(1);admin.sleepBlocks(1);miner.stop();

獲得交易結果:

{
    "jsonrpc": "2.0",
    "id": 2192787296,
    "method": "eth_getTransactionReceipt",
    "params": [
        "0xcce335377ff76cfa135c88fbc6b337539f03e7808f77473095a670104c3c8929"
    ]
}

返回:

{
    "jsonrpc": "2.0",
    "id": 2192787296,
    "result": {
        "blockHash": "0x8ef493560a75fcab08a04fc0dd2a903daa53952912e57bf1fe746361d05f4df5",
        "blockNumber": "0x136",
        "contractAddress": "0xfbd68b1fffd21ba3112583383c4b51d9f8a6e4ff",
        "cumulativeGasUsed": "0x16f7c",
        "from": "0xb338d763691dcfcff4720bc8f3e627901e239b30",
        "gasUsed": "0x16f7c",
        "logs": [],
        "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
        "status": "0x1",
        "to": null,
        "transactionHash": "0xcce335377ff76cfa135c88fbc6b337539f03e7808f77473095a670104c3c8929",
        "transactionIndex": "0x0"
    }
}

獲得合約地址:0xfbd68b1fffd21ba3112583383c4b51d9f8a6e4ff
調用合約:

{
    "jsonrpc": "2.0",
    "id": 171,
    "method": "eth_sendTransaction",
    "params": [
        {
            "data": "0x",
            "from": "0xb338d763691dcfcff4720bc8f3e627901e239b30",
            "to": "0xfbd68b1fffd21ba3112583383c4b51d9f8a6e4ff",
            "gas": "0x47b760"
        }
    ]
}

返回:

{
    "jsonrpc": "2.0",
    "id": 171,
    "result": "0xd7452ccafbff75e5653213f5324137c90d5b74acd683e193eb5a756a90e8dd79"
}

執(zhí)行一次挖礦

miner.start(1);admin.sleepBlocks(1);miner.stop();

查詢合約存儲信息

{
    "jsonrpc": "2.0",
    "id": 1115,
    "method": "eth_getStorageAt",
    "params": [
        "0xfbd68b1fffd21ba3112583383c4b51d9f8a6e4ff",
        "0x0",
        "latest"
    ]
}

返回

{
    "jsonrpc": "2.0",
    "id": 1115,
    "result": "0x0000000000000000000000000000000000000000000000000000000000000001"
}

完全正確

5、使用包裝前的wasm測試

采用4的方法,對包裝前的store.wasm測試了發(fā)布和調用,都是成功的,因此不理解為啥deploy-ewasm強調wasm需要通過chisel run處理wasm文件
找到原因了,chisel run處理后的合約發(fā)布后,保存到鏈上的是chisel run處理前的合約,這樣就可以保證合約在發(fā)布的時候不會被執(zhí)行,只有調用的時候才能夠執(zhí)行,另外也是通過這個包裝確保了合約在發(fā)布的時候可以調用哨兵合約進行檢查。
但是這塊也是個漏洞,因為不使用chisel run處理wasm文件,就發(fā)布合約,會規(guī)避了哨兵合約的檢查。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容