摘要
1、用solc 將solidity 代碼編譯成evm 字節(jié)碼
2多艇、用evm2wasm 將evm 轉(zhuǎn)化成wasm和wast 格式
準(zhǔn)備開發(fā)環(huán)境
1、安裝solidity
mac 上通過brew 安裝
$ brew install solidity
或者參照安裝教程
https://solidity.readthedocs.io/en/latest/installing-solidity.html#building-from-source
然后命令行輸入
$ solc --version
如果安裝成功會(huì)打印出來solc版本號(hào)
note:如果實(shí)在不愿意用命令行工具,也可以考慮使用在線編輯器https://remix.ethereum.org/
2醉者、安裝evm2wasm
首先確保已經(jīng)安裝nodejs,然后下載源碼 https://github.com/ewasm/evm2wasm
clone下來后披诗,先修改根目錄下的package.json 文件
"wabt": "^1.0.0"
改為
"wabt": "1.0.0"
然后撬即,在根目錄輸入
$ npm install
下載依賴庫可能會(huì)比較慢,可執(zhí)行js文件是 bin/evm2wasm.js
正式開工
1呈队、solc 編譯solidity 智能合約
創(chuàng)建一個(gè)solidity智能合約hello.sol剥槐,文件內(nèi)容如下
pragma solidity ^0.5.4;
contract HelloWorld {
function helloWorld() external pure returns (string memory) {
return "Hello, World!";
}
}
在hello.sol 所在目錄輸入編譯命令
$ solc --bin hello.sol -o hello
輸出文件HelloWorld.bin 位于hello 目錄下,將它重命名宪摧,以方便后續(xù)操作粒竖。可以看到輸出文件內(nèi)容是hex 格式的evm字節(jié)碼几于。
$ mv hello/HelloWorld.bin hello.evm
$ cat hello.evm
608060405234801561001057600080fd5b50610139806100206000396000f3fe6080604052348
01561001057600080fd5b5060043610610048576000357c01000000000000000000000000000
0000000000000000000000000000090048063c605f76c1461004d575b600080fd5b6100556100
d0565b604051808060200182810382528381815181526020019150805190602001908083836
0005b8381101561009557808201518184015260208101905061007a565b5050505090509081
0190601f1680156100c25780820380516001836020036101000a031916815260200191505b50
9250505060405180910390f35b60606040805190810160405280600d81526020017f48656c6c6
f2c20576f726c64210000000000000000000000000000000000000081525090509056fea16562
7a7a72305820fd3ae219ac96e3ff3152d3d6afc304cec55cc9685c2ecfa46f05e9dc69bafd6e0029
solc 這個(gè)工具功能很強(qiáng)大蕊苗,忍不住想嘗試一下獲取智能合約abi 的功能,雖然在下文中并沒有卵用沿彭。
$ solc --abi hello.sol
======= hello.sol:HelloWorld =======
Contract JSON ABI
[{"constant":true,"inputs":[],"name":"helloWorld","outputs":
[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"}]
2朽砰、evm2wasm 轉(zhuǎn)換成wasm
由于 bin/evm2wasm.js 這個(gè)工具只支持二進(jìn)制格式的evm字節(jié)碼,所以需要對(duì)它進(jìn)行一點(diǎn)兒改造喉刘,使之可以接受hex 格式的輸入瞧柔。
bytecode = Buffer.from(bytecode, 'hex')
只需要把上述代碼下邊添加一行代碼即可。
bytecode = Buffer.from(bytecode, 'hex')
bytecode = Buffer.from(bytecode.toString(), 'hex')
接下來執(zhí)行命令把wast 格式轉(zhuǎn)換成wasm 格式睦裳,前面的絕對(duì)路徑請(qǐng)自行修改T旃!廉邑!
/Users/ff/dev/install/evm2wasm-master/bin/evm2wasm.js -e hello.evm -o hello.wasm
用十六進(jìn)制編輯器打開生成的wasm 文件哥蔚。
0061736D 01000000 01080260 017E0060 00000213 01086574 68657265 756D0675
73654761 73000003 02010105 040100F4 03062106 7F014100 0B7F0141 600B7F01
41000B7F 0041A888 020B7E01 42000B7E 0142000B 07110206 6D656D6F 72790200
046D6169 6E00010A 37013501 027F417F 21000240 03400240 23024504 40410124
020C0105 23004100 46044000 05230021 01410024 0020010E 00020B0B 0B0B0B0B
3、evm2wasm 轉(zhuǎn)換成wast
命令與轉(zhuǎn)換成wasm 類似鬓催,前面的絕對(duì)路徑請(qǐng)自行修改7嗡亍!宇驾!
/Users/ff/dev/install/evm2wasm-master/bin/evm2wasm.js -e hello.evm -o hello.wast --wast
這是生成的wast 文件倍靡。
$ cat hello.wast
(module
(import "ethereum" "useGas" (func $useGas (param i64)))
(global $cb_dest (mut i32) (i32.const 0))
(global $sp (mut i32) (i32.const -32))
(global $init (mut i32) (i32.const 0))
;; memory related global
(global $memstart i32 (i32.const 33832))
;; the number of 256 words stored in memory
(global $wordCount (mut i64) (i64.const 0))
;; what was charged for the last memory allocation
(global $prevMemCost (mut i64) (i64.const 0))
;; TODO: memory should only be 1, but can't resize right now
(memory 500)
(export "memory" (memory 0))
(func $main
(export "main")
(local $jump_dest i32) (local $jump_map_switch i32)
(set_local $jump_dest (i32.const -1))
(block $done
(loop $loop
(block $0
(if
(i32.eqz (get_global $init))
(then
(set_global $init (i32.const 1))
(br $0))
(else
;; the callback dest can never be in the first block
(if (i32.eq (get_global $cb_dest) (i32.const 0))
(then
(unreachable)
)
(else
;; return callback destination and zero out $cb_dest
(set_local $jump_map_switch (get_global $cb_dest))
(set_global $cb_dest (i32.const 0))
(br_table $0 (get_local $jump_map_switch))
))))))))