Commit 6b0232cb authored by WuEcho's avatar WuEcho

add web3 useing

parent 0544e252
...@@ -401,4 +401,95 @@ func TestCall(t *testing.T) { ...@@ -401,4 +401,95 @@ func TestCall(t *testing.T) {
``` ```
### web3使用说明
可以使用 `web3.js` 很方便的在链上发布和使用 `wasm` 合约,我们提供了一个简单的封装用以演示 `hello-wasm` 的部署和调用合约中提供的三个方法
可以将 [test-wasm-js](https://code.wuban.net.cn/cmpchain/ewasm-rust-demo/tree/master/test-wasm-js) 目录下的演示代码下载到本地,
代码依赖 `nodejs` 环境以及 `npm` 工具,下载后 `npm install` 安装依赖并修改 `config.js` 填入正确的参数即可通过如下操作完成部署和使用合约
#### config.js
配置:
* ethereumUri : 链的 rpc 接口地址
* chainId : 可以通过 admin.nodeInfo 查看当前节点的 chainId,需要正确填写
* gasLimit : 1800 万gas
* gasPrice : 18gwei 的 price
* keyStore : 在keyStore 中管理的私钥文件内容,是一个 json
* password : 私钥文件的密码
* wasm_path : 要发布的合约 filepath
* methods : 合约提供的函数,类似 abi 的定义
例如:
```javascript
const config = {
'ethereumUri': 'http://127.0.0.1:8545',
'chainId': 738,
'gasLimit': 15000000,
'gasPrice': 18000000000,
'keyStore': '{"address":"286a713af771b89f7bd2bfb46832da710780552e","crypto":{"cipher":"aes-128-ctr","ciphertext":"c4b50bcc8127a99a9b7fa2484e3494032435f1f3bdc829b10a0b87bfe6cb6215","cipherparams":{"iv":"be2fa649e7cf0516db8f221371dbdb93"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"3fde3e3d2d2e4576675868f443aca47a289ef913d46f973f405c79092d5b65dd"},"mac":"8e673dbf025e88115f2b913ec891a41e47b8dcdca572b3e3a96584bb1ca2cb78"},"id":"014df77c-b7fd-484e-8e1e-5d6a5a9fa902","version":3}',
'password': '123456',
'wasm_path': '/Users/wuxinyang/Desktop/MyGo/src/rust/hello-wasm/pkg/hello_wasm_bg.wasm',
'methods': {'put': 'put:{},{}', 'get': 'get:{}', 'GetCounter': 'GetCounter'}
}
module.exports = config
```
#### index.js
测试程序的入口,正确填写配置后使用 `npm test` 会默认执行这个脚本
```javascript
function test_put(...params) {
let put_method = config.methods['put']
put_method = format(put_method, params[0], params[1])
let data = web3.utils.toHex(put_method)
contract.runWriteMethod(data)
}
function test_get(key) {
let get_method = config.methods['get']
get_method = format(get_method, key)
let data = web3.utils.toHex(get_method)
contract.runReadMethod(data).then(value => {
console.log(`value==>${web3.utils.hexToString(value)}`)
test_GetCounter()
})
}
function test_GetCounter() {
let getcounter_method = config.methods['GetCounter']
let data = web3.utils.toHex(getcounter_method)
contract.runReadMethod(data).then(counter => {
console.log(`counter==>${web3.utils.hexToNumber(counter)}`)
})
}
//部署并调用合约3个方法
//此测试方法每次调用时都会重新部署一次 hello-wasm 合约,
function test() {
// 2:合约部署成功后触发该事件,通过 put(key,val) 函数插入状态
contract.once('contract_address', contract_address => {
console.log(`contract_address==>${contract_address}`)
contract.contract_address = contract_address
test_put('foo', 'bar')
})
// 3:put成功后触发该事件,通过 get(key) 函数获取刚刚插入的状态
// 同时通过合约的 GetCounter 函数获取合约状态变更次数
contract.once('runWriteMethod_success', ()=>{
test_get('foo')
})
// 1:部署合约
contract.pub()
}
//脚本入口函数
test()
```
const fs = require('fs')
const Web3 = require('web3')
const co = require('co')
const thunk = require('thunkify')
const Tx = require('ethereumjs-tx')
const EventEmitter = require('events').EventEmitter
const config = require('./config.js')
class Contract extends EventEmitter {
constructor() {
super()
this.web3 = new Web3(new Web3.providers.HttpProvider(config.ethereumUri))
this.getTransactionCount = thunk(this.web3.eth.getTransactionCount)
}
pub() {
let _this = this
let rs = fs.createReadStream(config.wasm_path)
rs.on('data', function (data) {
data = data.toString('hex')
_this._sendTransaction('0x' + data)
})
}
runReadMethod(data) {
let _this = this
return this.web3.eth.call({
to: _this.contract_address,
data: data
})
}
runWriteMethod(data) {
this._sendTransaction(data)
}
_sendTransaction(data) {
let decryptObj = this.web3.eth.accounts.decrypt(config.keyStore, config.password)
let address = decryptObj.address
let privateKey = decryptObj.privateKey
privateKey = Buffer.from(privateKey.substring(2), 'hex')
let _this = this
co(function* () {
let nonce = yield _this.getTransactionCount(address, 'pending')
let rawTransaction = {
"from": address,
"to": _this.contract_address ? _this.contract_address : '',
"nonce": "0x" + nonce.toString(16),
"gasPrice": _this.web3.utils.toHex(config.gasPrice),
"gasLimit": _this.web3.utils.toHex(config.gasLimit),
"data": data,
"chainId": _this.web3.utils.toHex(config.chainId)
}
let tx = new Tx(rawTransaction)
tx.sign(privateKey)
let serializedTx = tx.serialize()
let sign = '0x' + serializedTx.toString('hex')
try {
let date = new Date();
let transaction = _this.web3.eth.sendSignedTransaction(sign)
transaction.on('transactionHash', hash => {
console.log(`[${date.toLocaleString()}] hash ${hash}`);
});
transaction.on('receipt', receipt => {
if (receipt.contractAddress) {
_this.emit('contract_address', receipt.contractAddress)
} else {
_this.emit('runWriteMethod_success')
}
});
} catch (error) {
console.log('sendSignedTransaction err:', error);
}
})
}
}
module.exports = new Contract()
const config = {
'ethereumUri': 'http://127.0.0.1:8545',
'chainId': 738,
'gasLimit': 15000000,
'gasPrice': 18000000000,
'keyStore': '{"address":"286a713af771b89f7bd2bfb46832da710780552e","crypto":{"cipher":"aes-128-ctr","ciphertext":"c4b50bcc8127a99a9b7fa2484e3494032435f1f3bdc829b10a0b87bfe6cb6215","cipherparams":{"iv":"be2fa649e7cf0516db8f221371dbdb93"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"3fde3e3d2d2e4576675868f443aca47a289ef913d46f973f405c79092d5b65dd"},"mac":"8e673dbf025e88115f2b913ec891a41e47b8dcdca572b3e3a96584bb1ca2cb78"},"id":"014df77c-b7fd-484e-8e1e-5d6a5a9fa902","version":3}',
'password': '123456',
'wasm_path': '/app/rusthome/hello-wasm/pkg/hello_wasm_bg.wasm',
'methods': {'put': 'put:{},{}', 'get': 'get:{}', 'GetCounter': 'GetCounter'}
}
module.exports = config
const contract = require('./Contract')
const format = require('string-format')
const Web3 = require('web3')
const web3 = new Web3()
const config = require('./config')
function test_put(...params) {
let put_method = config.methods['put']
put_method = format(put_method, params[0], params[1])
let data = web3.utils.toHex(put_method)
contract.runWriteMethod(data)
}
function test_get(key) {
let get_method = config.methods['get']
get_method = format(get_method, key)
let data = web3.utils.toHex(get_method)
contract.runReadMethod(data).then(value => {
console.log(`value==>${web3.utils.hexToString(value)}`)
test_GetCounter()
})
}
function test_GetCounter() {
let getcounter_method = config.methods['GetCounter']
let data = web3.utils.toHex(getcounter_method)
contract.runReadMethod(data).then(counter => {
console.log(`counter==>${web3.utils.hexToNumber(counter)}`)
})
}
function test() {
contract.once('contract_address', contract_address => {
console.log(`contract_address==>${contract_address}`)
contract.contract_address = contract_address
test_put('foo', 'bar')
})
contract.once('runWriteMethod_success', ()=>{
test_get('foo')
})
contract.pub()
}
test()
{
"name": "wasm_contract_test",
"version": "1.0.0",
"description": "wasm contract publish and run with MetaVM",
"main": "index.js",
"scripts": {
"test": "node index.js"
},
"keywords": [
"wasm",
"contract",
"pdx"
],
"author": "",
"license": "ISC",
"dependencies": {
"co": "^4.6.0",
"ethereumjs-tx": "1.3.7",
"string-format": "^2.0.0",
"thunkify": "^2.1.2",
"web3": "1.0.0-beta.34"
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment