介绍
@velma/ethereumjs-vm 是一个 Ethereum 虚拟机,可以在本地执行智能合约,并提供了一系列的 API,方便开发者在 dApp 中使用。该 npm 包基于 EthereumJS 实现,支持 EVM 和 eWASM。
安装
使用 npm 或 yarn 安装:
npm install @velma/ethereumjs-vm
或者
yarn add @velma/ethereumjs-vm
快速上手
可以使用以下代码在本地创建一个简单的智能合约:
-- -------------------- ---- ------- ----- - --- --- - - -------------------------------- ----- ------ - ------------------ ----- ---- - ----------------------------- ----- ------------ - - -------- ------ ------ ----- -- ----- -- - --- ---- ---------------- ---- --- ---------- ----- --------- ---------- -- ------------- ----- ---- -- - -------------------- ---------------------------------------- -- ------- ---------------------------------------------------------------- --------------------------------------- -- ------- - ---
在上述代码中,我们首先引入了 VM 和 abi,它们都是 @velma/ethereumjs-vm 中的常用 API。然后我们定义了一个 code
和一个 initialState
,并创建了一个 VM 实例。
接着我们使用 runTx
方法执行了一个交易,该交易的 code
是上面定义的 code
,gasLimit
是指定的 gas 上限,initialState
是账户的状态。
如果执行成功,我们就可以通过 res.return
获取返回值,并通过 res.vm.gasUsed
获取使用的 gas 量。
API
VM
VM 是 @velma/ethereumjs-vm 的主要 API,可以用于在本地执行智能合约。VM 有以下重要方法:
runTx
用于执行交易。
vm.runTx(tx, initialState, callback)
参数:
tx
:Object,表示待执行的交易。交易包含以下属性:to
:String,表示接收地址,可选。from
:String,表示发送地址。value
:String,表示发送的 ETH 数量,可选。gasPrice
:String,表示 gas 价格。gasLimit
:String,表示 gas 上限。nonce
:String,表示 nonce,可选。data
:String,表示待执行的合约代码,可选。
initialState
:Object,表示合约的初始状态。对象包含以下属性:balance
:String,表示 ETH 余额。nonce
:String,表示 nonce。code
:String,表示智能合约的代码,可选。
callback
:Function,用于接收执行结果的回调函数。
runCall
用于执行一个合约,并返回输出值。
vm.runCall(tx, blockNumber, callback)
参数:
tx
:Object,表示待执行的交易。交易包含以下属性:to
:String,表示接收地址。from
:String,表示发送地址。value
:String,表示发送的 ETH 数量,可选。gasPrice
:String,表示 gas 价格。gasLimit
:String,表示 gas 上限。nonce
:String,表示 nonce,可选。data
:String,表示待执行的合约代码,可选。
blockNumber
:Number,表示区块号。callback
:Function,用于接收执行结果的回调函数。
abi
abi 用于处理智能合约的 ABI(Application Binary Interface)。ABI 是智能合约的接口,包含了合约地址、函数名和参数列表等信息。通过 ABI 我们可以与智能合约进行交互。在 @velma/ethereumjs-vm 中,我们可以使用 abi 的 encodeFunctionCall
方法编码函数调用,或使用 decodeCall
方法解码函数返回值。
encodeFunctionCall
用于编码函数调用,返回使用 ABI 编码后的数据。
abi.encodeFunctionCall(jsonInterface, args)
参数:
jsonInterface
:Object,表示函数的 ABI。args
:Array,表示函数的参数列表。
例如,对于以下合约:
-- -------------------- ---- ------- -------- ------------- - ---- ------ ----- -------- -------- -- ------ - ---- - -- - -------- ----- ------ ---- ------- ------ - ------ ----- - -
我们可以使用以下代码编码调用 set 函数:
-- -------------------- ---- ------- ----- ----------- - - --------- ------ ------- -- ----- ---- ----- --------- --- ----- ------ -------- --- -------- ------ ---------------- ------------- ----- ----------- -- ----- ---------- - ---- ----- ------------ - ----------------------------------- -------------- -------------------------- -- ------- -------------------------------------------------------------------------
decodeCall
用于解码函数返回值,返回解码后的数据。
abi.decodeFunctionResult(jsonInterface, output)
参数:
jsonInterface
:Object,表示函数的 ABI。output
:String,表示函数的返回值。
例如,对于以下合约:
-- -------------------- ---- ------- -------- ------------- - ---- ------ ----- -------- -------- -- ------ - ---- - -- - -------- ----- ------ ---- ------- ------ - ------ ----- - -
我们可以使用以下代码解码调用 get 函数的返回值:
-- -------------------- ---- ------- ----- ----------- - - --------- ----- ------- --- ----- ------ -------- -- ----- --- ----- --------- --- -------- ------ ---------------- ------- ----- ----------- -- ----- ----------- - --------------------------------------------------------------------- ----- ------------ - ------------------------------------- ------------- -------------------------- -- ------- - ----- -
示例代码
下面是一个完整的使用 @velma/ethereumjs-vm 的示例代码,该代码使用 JavaScript 定义了一个简单的 ERC20 智能合约。
-- -------------------- ---- ------- ----- - --- --- - - -------------------------------- ----- ------ - ------------------ ----- ------------- - - - ----- ----------- ------- - - ----- ---------- ----- ----- -- - ----- ---------- ----- -------- -- -- -------- -- ----- ------- ----- -- --- -- - ----- ------------ ------- -- ----- ---------- ----- -------- --- -------- -- ----- ---------- ----- --------- --- -- -- ----- ------------ - - ------ -------- ------- -------- ----------- - ------- -------- -- ----- --------- -------- ---------------- ---- ------- ------- ------ ------- ----- -------- - ---------------------------- -- ------- ---- ------ ---------- -------------------- -- ------- ------------- -- ------- ------ ----- - -------- ----------------- ------- ------ ---- ------- -------- -------- - ------ ----------------- - - -- ----- -------------- - --------------- ----- -------------- - - -------- --------------- ------ ------ ----- ------------- -- ----------------------- -- -- - --- --- --- -------- --- --------- ------------- -- - -- - --- ---- ---------------- ---- --- -------- - ------------------------------- ------- - ----------------- --- ---------- ------ ------- --------- ---- -- - ----------- - --- -------- ----- ---------------------------------------- ----------- -- --------- ----- ----- -- - -------------------- ----- ------- - ------------------------------------------ ------------- ------------------------------ ---------------- ------- -- -- --- ---------- -------- -------- ---- -- - ----- ---------------- - --------- --------- - --- -------- ----- ---------------------------------------- - -------- --------------------------- --- --------- ----------- --------- ------- ------ ------- -- --------------- ----- ----- -- - -------------------- ----------- - --- -------- ----- ---------------------------------------- ----------- -- --------- ----- ----- -- - -------------------- ----- ------- - ------------------------------------------ ------------- ------------------------------ ------------------------- - ---------------------------------------- ------- -- -- -- -- --- ---
上面的代码中,我们首先引入了 VM 和 abi,然后定义了一个 ERC20 合约的 ABI 和合约代码。接着我们创建了一个 VM 实例,并使用 VM 的 compileScript
方法编译了合约代码,然后获取了合约地址。
我们通过两个测试用例展示了如何调用合约的函数。第一个测试用例调用了 balanceOf
函数,以获取账户余额。第二个测试用例调用了 transfer
函数,以转移账户余额。
总结
@velma/ethereumjs-vm 是一个非常有用的 npm 包,可以帮助前端开发者在本地运行智能合约,提高了合约的开发效率。本文通过一个简单的 ERC20 合约示例,较详细地介绍了 @velma/ethereumjs-vm 的使用方法和 API,希望对大家学习或开发智能合约有所帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/60065f7a238a385564ab69e9