1.设置账户:

ethereumjs-vm/examples/run-transactions-complete/key-pair.json

{
"secretKey": "3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511",
"publicKey": "0406cc661590d48ee972944b35ad13ff03c7876eae3fd191e8a2f77311b0a3c6613407b5005e63d7d8d76b89d5f900cde691497688bb281e07a5052ff61edebdc0"
}

2.设置的要运行的交易:

ethereumjs-vm/examples/run-transactions-complete/raw-tx1.json

{
"nonce": "0x00",
"gasPrice": "0x09184e72a000",
"gasLimit": "0x90710",
"data": "0x60606040526103dd806100126000396000f360606040526000357c010000000000000000000000000000000000000000000000000000000090048063454a2ab31461004f578063b9a2de3a14610091578063edd481bb146100d35761004d565b005b6100656004808035906020019091905050610189565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100a760048080359060200190919050506102d2565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100e960048080359060200190919050506100ff565b6040518082815260200191505060405180910390f35b600060016000818150548092919060010191905055905080508143016000600050600083815260200190815260200160002060005060000160005081905550336000600050600083815260200190815260200160002060005060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b919050565b60006000600060005060008481526020019081526020016000206000509050346012600a8360010160005054011811806101c95750438160000160005054115b1561022d573373ffffffffffffffffffffffffffffffffffffffff16600034604051809050600060405180830381858888f19350505050508060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691506102cc565b8060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008260010160005054604051809050600060405180830381858888f1935050505050338160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055503481600101600050819055503391506102cc565b50919050565b600060006000600050600084815260200190815260200160002060005090508060000160005054431015156103d6578060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008260010160005054604051809050600060405180830381858888f19350505050506000816001016000508190555060008160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055506000816000016000508190555060008160030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b5b5091905056"
}

上面这个交易是设置了一个合约

ethereumjs-vm/examples/run-transactions-complete/raw-tx2.js

var bidSig = '0x454a2ab3'
var time = '' var rawTx2 = {
nonce: '0x01',
gasPrice: '0x09184e72a000',
gasLimit: '0x20710',
value: '0x10',
to: '0x692a70d2e424a56d2c6c27aa97d1a86395877b3a',
data: bidSig + time
} module.exports = rawTx2

这个交易则是调用了合约中的某个函数

3.运行

ethereumjs-vm/examples/run-transactions-complete/index.js

/*
* Example - Run code contain within transactions
*
*
* Execute it with `node index.js`
*/ var Buffer = require('safe-buffer').Buffer // use for Node.js <4.5.0
var async = require('async')
var VM = require('./../../index.js')
var Account = require('ethereumjs-account')
var Transaction = require('ethereumjs-tx')
var Trie = require('merkle-patricia-tree')
var rlp = require('rlp')
var utils = require('ethereumjs-util') // creating a trie that just resides in memory
var stateTrie = new Trie() // create a new VM instance
var vm = new VM({state: stateTrie}) //stateTrie就是区块上的state merkle-patricia树,用于存储区块上的所有账户的信息 // import the key pair
// pre-generated (saves time)
// used to sign transactions and generate addresses
var keyPair = require('./key-pair') var createdAddress // Transaction to initalize the name register, in this case
// it will register the sending address as 'null_radix'
// Notes:
// - In a transaction, all strings as interpeted as hex
// - A transaction has the fiels:
// - nonce
// - gasPrice
// - gasLimit
// - data
var rawTx1 = require('./raw-tx1') // 2nd Transaction
var rawTx2 = require('./raw-tx2') // sets up the initial state and runs the callback when complete
// 设置初始状态,在完成时运行回调函数
function setup (cb) {
// the address we are sending from
var publicKeyBuf = Buffer.from(keyPair.publicKey, 'hex')
var address = utils.pubToAddress(publicKeyBuf, true)
console.log(address.toString('hex'));//账户address为ca35b7d915458ef540ade6068dfe2f44e8fa733c
// create a new account
var account = new Account()//创建一个空账户
// give the account some wei.
// Note: this needs to be a `Buffer` or a string. All
// strings need to be in hex.
account.balance = '0xf00000000000000001' //设置账户balance余额的值 // store in the trie,将该账户存储到前缀树中
stateTrie.put(address, account.serialize(), cb) //将该address与账户状态的信息相关联并存储在了区块链上的state前缀树上,区块头上的stateRoot就是该state前缀树的root值
} // runs a transaction through the vm
function runTx (raw, cb) {
// create a new transaction out of the json
var tx = new Transaction(raw) // tx.from,对该交易进行签名
tx.sign(Buffer.from(keyPair.secretKey, 'hex')) console.log('----running tx-------')
// run the tx \o/
vm.runTx({//运行交易
tx: tx
}, function (err, results) {
createdAddress = results.createdAddress //返回运行该交易生成的合约地址信息
// log some results
console.log('gas used: ' + results.gasUsed.toString()) //得到使用的gas值
console.log('returned: ' + results.vm.return.toString('hex'))
if (createdAddress) {
console.log('address created: ' +
createdAddress.toString('hex'))
} cb(err)
})
} var storageRoot // used later // Now lets look at what we created. The transaction
// should have created a new account for the contract
// in the trie.Lets test to see if it did.
// 交易应该为在前缀树上的合约创建了一个账户,即合约账户。下面查看是否如此
function checkResults (cb) {
// fetch the new account from the trie.
stateTrie.get(createdAddress, function (err, val) {//val为该合约帐号的RLP序列化的值account.serialize()
var account = new Account(val)//所以可以用它来初始化一个账户,然后得到下面的信息 storageRoot = account.stateRoot // used later! :)
console.log('------results------')
console.log('nonce: ' + account.nonce.toString('hex'))
console.log('balance in wei: ' + account.balance.toString('hex'))
console.log('stateRoot: ' + storageRoot.toString('hex'))
console.log('codeHash:' + account.codeHash.toString('hex'))
console.log('-------------------')
cb(err)
})
} // So if everything went right we should have "null_radix"
// stored at "0x9bdf9e2cc4dfa83de3c35da792cdf9b9e9fcfabd". To
// see this we need to print out the name register's
// storage trie.
//如果上面的部分都成功运行的话,那么应该会有value = "null_radix"存储在key = "0x9bdf9e2cc4dfa83de3c35da792cdf9b9e9fcfabd"中
//要看到这一点,我们需要打印出名字寄存器的存储前缀树
function checkResults2 (cb) {
// fetch the new account from the trie.
stateTrie.get('0x9bdf9e2cc4dfa83de3c35da792cdf9b9e9fcfabd', function (err, val) {//并没有得到上面所说的value = "null_radix" ???
console.log('------results2------')
console.log(val);
console.log('------------')
cb(err)
})
} // reads and prints the storage of a contract
// 读取并打印合约的存储
function readStorage (cb) {
// we need to create a copy of the state root
var storageTrie = stateTrie.copy()
console.log(storageRoot.toString('hex'));//56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421,即null的RLP编码的Keccak-256 hash值
console.log(storageTrie.root.toString('hex'));//a7d73ff53f4b8722d594cb0462907879e58d95e5784c05510ce5419c52331be5
// Since we are using a copy we won't change the
// root of `stateTrie`
// 由于我们使用的是副本,所以不会更改stateTrie的根.但是运行的结果发现是改了的
// 将下面的注释掉,才能够通过stream.on('data'...得到前缀树中的信息
// storageTrie.root = storageRoot //将刚刚上面生成的合约账户的stateRoot赋值到storageTrie.root
console.log(storageTrie.root.toString('hex'));//storageTrie.root = storageRoot后storageTrie.root变为56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421,即null的RLP编码的Keccak-256 hash值,这样下面的stream.on('data'...是得不到返回值的
var stream = storageTrie.createReadStream() //创建可读流 console.log('------Storage------') // prints all of the keys and values in the storage trie
// 打印所有在存储前缀树中的keys和values
stream.on('data', function (data) {
// remove the 'hex' if you want to see the ascii values
console.log('key: ' + data.key.toString('hex'))
// console.log('Value: ' + rlp.decode(data.value).toString())
console.log('Value: ');
rlp.decode(data.value).map(item => {//数组内的值分别是nonce,balance,stateRoot,codehash
console.log(item.toString('hex'));
})
}) stream.on('end', cb)
} // run everything
async.series([//按下面的顺序进行运行
setup,
async.apply(runTx, rawTx1),//运行了两个交易
async.apply(runTx, rawTx2),
checkResults,
checkResults2,
readStorage
]) // Now when you run you should see a complete trace.
// `onStep` provides an object that contains all the
// information on the current state of the `VM`.

返回:

userdeMBP:run-transactions-complete user$ node index.js
ca35b7d915458ef540ade6068dfe2f44e8fa733c //从key-pair.json得到的账户地址
----running tx-------
gas used:
returned: 60606040526000357c010000000000000000000000000000000000000000000000000000000090048063454a2ab31461004f578063b9a2de3a14610091578063edd481bb146100d35761004d565b005b6100656004808035906020019091905050610189565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100a760048080359060200190919050506102d2565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100e960048080359060200190919050506100ff565b6040518082815260200191505060405180910390f35b600060016000818150548092919060010191905055905080508143016000600050600083815260200190815260200160002060005060000160005081905550336000600050600083815260200190815260200160002060005060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b919050565b60006000600060005060008481526020019081526020016000206000509050346012600a8360010160005054011811806101c95750438160000160005054115b1561022d573373ffffffffffffffffffffffffffffffffffffffff16600034604051809050600060405180830381858888f19350505050508060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691506102cc565b8060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008260010160005054604051809050600060405180830381858888f1935050505050338160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055503481600101600050819055503391506102cc565b50919050565b600060006000600050600084815260200190815260200160002060005090508060000160005054431015156103d6578060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008260010160005054604051809050600060405180830381858888f19350505050506000816001016000508190555060008160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055506000816000016000508190555060008160030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b5b5091905056
address created: 692a70d2e424a56d2c6c27aa97d1a86395877b3a //生成的合约账户地址
----running tx-------
gas used:
returned:
------results------
nonce:
balance in wei:
stateRoot: 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 //null的RLP编码的Keccak-256 hash值
codeHash:c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 //即空字符串hash值,说明为外部账户
-------------------
------results2------
null
------------
56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421
a7d73ff53f4b8722d594cb0462907879e58d95e5784c05510ce5419c52331be5
a7d73ff53f4b8722d594cb0462907879e58d95e5784c05510ce5419c52331be5
------Storage------
key: 0000000000000000000000000000000000000000 //空账户,默认存在;有时省略账户时则使用它
Value: 2f8ae2f307888000
56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421
c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
key: 692a70d2e424a56d2c6c27aa97d1a86395877b3a
Value: 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421
a6db6bcd1c3757abef01cdf587304df3698a3b1e6b93667fbe87072d261ee7e1 //不为空字符串hash值,说明为合约账户
key: ca35b7d915458ef540ade6068dfe2f44e8fa733c //从key-pair.json得到的账户地址
Value:
//使用其运行了两个交易,所以nonce为2
efd0751d0cf8778001
56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421
c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470

ethereumjs-vm/examples/run-transactions-complete的更多相关文章

  1. ethereumjs/browser-builds

    https://github.com/ethereumjs/browser-builds ethereumjs - Browser Builds This repository contains br ...

  2. ethereumjs/ethereumjs-vm-4-tests

    根据代码发现还要了解的模块有: ethereumjs/merkle-patricia-tree -对应数据存储的数据结构 ethereumjs-blockchain —— 区块链 ethereumjs ...

  3. Qt Examples Qt实例汇总

    ActiveQt Examples Using ActiveX from Qt applications. Animation Framework Examples Doing animations ...

  4. Extended VM Disk In VirtualBox or VMware (虚拟机磁盘扩容)

    First, Clean VM all snapshot, and poweroff your VM. vmdk: vmware-vdiskmanager -x 16GB myDisk.vmdk vd ...

  5. PatentTips - Interrupt redirection for virtual partitioning

    BACKGROUND The present disclosure relates to the handling of interrupts in a environment that utiliz ...

  6. Postgresql-xl 调研

    Postgresql-xl 调研 来历 这个项目的背后是一家叫做stormDB的公司.整个代买基于postgres-xc.开源版本应该是stormdb的一个分支. In 2010, NTT's Ope ...

  7. Java Annotations: Explored & Explained--转载

    原文地址:http://www.javacodegeeks.com/2012/08/java-annotations-explored-explained.html One of the many w ...

  8. Understanding User and Kernel Mode

    https://blog.codinghorror.com/understanding-user-and-kernel-mode/ Continue Discussion92 repliesJan ' ...

  9. Java Annotation 机制源码分析与使用

    1 Annotation 1.1 Annotation 概念及作用      1.  概念 An annotation is a form of metadata, that can be added ...

  10. MongoDB - MongoDB CRUD Operations, Query Documents

    Query Method MongoDB provides the db.collection.find() method to read documents from a collection. T ...

随机推荐

  1. ASP.Net之一般处理程序

    1.静态语言和动态语言 静态语言:在服务器端,不会被执行,直接作为 字符串 发回给浏览器,由浏览器运行的语言( HTML+CSS+JS).   动态语言:在服务端,会被服务器端的某种语言的虚拟机执行的 ...

  2. hdu 1880 魔咒词典 (字符串哈希)

    魔咒词典 Time Limit: 8000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  3. C# 设计模式·创建型模式

    面试问到这个··答不出来就是没有架构能力···这里学习一下···面试的时候直接让我说出26种设计模式··当时就懵逼了··我记得好像之前看的时候是23种的 还有3个是啥的··· 这里先列出几种创建型模式 ...

  4. js比较好的一些方法

    js里面有些方法比较容易忘记,但却很实用,很好用的一些方法.在此记录: 1.Math.ceil(x) — 返回大于等于数字参数的最小整数(取整函数),对数字进行上舍入 2.Math.floor(x)– ...

  5. drupal的权限设置

    通过hook_menu()设置url的权限,有两种方式: 方式一:定义函数,通过 access callback 'access callback' => 'fun()', function f ...

  6. JS判断客户端是手机还是PC的2个代码

    搬了下砖 function IsPC() { var userAgentInfo = navigator.userAgent; var Agents = ["Android", & ...

  7. Android学习笔记(4)----Rendering Problems(The graphics preview in the layout editor may not be accurate)

    在Android Studio中新建了一个 setting.xml 文件,布局好文件后,从 Text 界面切换到 Design 界面,显示了如下错误: 网上搜寻 The graphics previe ...

  8. JS Error 内置异常类型 处理异常 Throw语句

    Exceptional Exception Handling in JavaScript       MDN资料 Anything that can go wrong, will go wrong. ...

  9. 5 TensorFlow实战Google深度学习框架一书中的错误两处(交叉熵定义有误)

    第一处: 书中62页定义的交叉熵函数定义有误,虽然这个所谓交叉熵的数值能够减少,但是是不能提升预测性能的,因为定义就错了. 我已经将预测过程可视化,直接将交叉熵改为我的,或者用原书的,就可以看到预测结 ...

  10. VUE知识day2

    VUE用途 VUE:是用来做单页面的 掘金网单击时会创建对象与销毁,减少与服务器的交互 1模块使用------------------- 1导出------------ export default ...