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. [PHP] 从 PHP 5.3.X 迁移到 PHP 5.6.X不兼容点

    从 PHP 5.3.X 迁移到 PHP 5.4.X不兼容点: 1.不再支持 安全模式 2.移除 魔术引号,设置 magic_quotes_gpc 系列将不会生效 3.Salsa10 和 Salsa20 ...

  2. PHP高级工程师面试 - 笔试题

    Part1:HTTP协议 1.状态码的含义 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码. 代码 说明 100 (继续) 请求者应当继续提出请求. 服务器返回此代码表示已收到请求 ...

  3. Ajax 之XMLHttpRequest讲解

    一直以来都听别人说Ajax,今天终于接触到了.......... 一.什么是Ajax? 答: AJAX即“Asynchronous Javascript And XML”(异步JavaScript和X ...

  4. csharp:A Custom CheckedListBox with Datasource

    /// <summary> /// (eraghi) /// Custom CheckedListBox with binding facilities (Value property) ...

  5. BZOJ1927: [Sdoi2010]星际竞速(最小费用最大流 最小路径覆盖)

    题意 题目链接 Sol 看完题不难想到最小路径覆盖,但是带权的咋做啊?qwqqq 首先冷静思考一下:最小路径覆盖 = \(n - \text{二分图最大匹配数}\) 为什么呢?首先最坏情况下是用\(n ...

  6. BZOJ5068: 友好的生物(状压 贪心)

    题意 题目链接 Sol 又是一道神仙题??.. 把绝对值拆开之后状压前面的符号?.. 下界显然,但是上界为啥是对的呀qwq.. #include<bits/stdc++.h> using ...

  7. linux 查看在线服务进程

    输入命令:netstat -ltunp  注意,这个-与l之间是没有空格的 要对进程进行监测和控制,首先必须要了解当前进程的情况,也就是需要查看当前进程, 而ps命令(Process Status)就 ...

  8. Alaya Webdav Server 0.0.10 发布

    Alaya Webdav Server 0.0.10 修复了很多 bug,Webdav 'Copy' 可以使用了. Alaya 是一个提供 WebDAV 支持的 Web 服务器,支持 HTTPS 和 ...

  9. v-model实现

    v-model就是输入的值实时显示的目的,如果纯粹写登录页面的form控件没有实时显示的需求 就不用绑定v-model.

  10. python django 环境搭建

    一. 版本选择 Django 1.5.x 支持 Python 2.6.5 Python 2.7, Python 3.2 和 3.3. Django 1.6.x 支持 Python 2.6.X, 2.7 ...