铂链第5课 如何在BOTTOS上搭建第一个DAPP应用[C++程
1,摘要
本文在学习者已完成BOTTOS本地节点搭建,钱包创建的前提下,演示如何通过前端调用BOTTOS智能合约程序(C++程序)查询交易执行结果和SDK调用的方法。
2, 实践内容
2.1 本地节点已启动,账号已创建
(1) 重启节点
本文假设你已经按照《铂链第2课 如何部署节点并加入BOTTOS测试网络?》完成了本地开发环境的部署。
如果重启虚拟机后,需要重启下本地节点。
在命令框进入BOTTOS安装目录,启动本地节点:./bottos --delegate=bottos --enable-wallet
【成功执行结果】
duncanwang@ubuntu64bit-server:~$ cd ~/go/src/github.com/bottos
duncanwang@ubuntu64bit-server:~/go/src/github.com/bottos$ ./bottos --delegate=bottos --enable-wallet
InsertBlock, number:6641, time:2019-01-06 10:55:27, delegate:bottos, trxn:0, hash:8af243f169b361c142a20f15fa45c47046406c60ba3ad3a9c168b41ec3e63e82, prevHash:b79a5c31a75333f357ddaeb98ed5d29b30655378d2f503d74c179c1551ee390e, version:1.0.0
InsertBlock, number:6642, time:2019-01-06 10:55:30, delegate:bottos, trxn:0, hash:b11bf02f345cbc95d330154080e7a4638026dda1693167e900138f18d3507ef4, prevHash:8af243f169b361c142a20f15fa45c47046406c60ba3ad3a9c168b41ec3e63e82, version:1.0.0
InsertBlock, number:6643, time:2019-01-06 10:55:33, delegate:bottos, trxn:0, hash:4b7c0b9195d1fec055d2e3f71276f988a887fae8cd069db2ef531738f8b6937d, prevHash:b11bf02f345cbc95d330154080e7a4638026dda1693167e900138f18d3507ef4, version:1.0.0
...
(2)已创建账户信息
本文假设你已经按照《铂链第3课 BOTTOS账户体系(密钥对/账号/钱包)的创建和管理》完成了账号的创建。没有创建好账号的参考该文完成账号创建。
【账户信息】
(1)账号名称:wangdenghui
密钥对:
public_key: 04692be71819302246bcfde268ff0e697d11a9493eac9f8cda1a0f0482fd1e87583d5844f072b0abfd43ffbd33ef804e19e148ca5c1518fd0f01bbc4b63cb7c6ae
private_key: e78c1801ca06099552afa86ea2ca38bd12fc8e5a8e817c3211074ab652c66ddf
账户余额:800BTO
质押情况:100 BTO for time
100 BTO for space
(2)账号名称:bottos
密钥对:
PrivateKey = "b799ef616830cd7b8599ae7958fbee56d4c8168ffd5421a16025a398b8a4be45"
PublicKey = "0454f1c2223d553aa6ee53ea1ccea8b7bf78b8ca99f3ff622a3bb3e62dedc712089033d6091d77296547bc071022ca2838c9e86dec29667cf740e5c9e654b6127f"
账户余额:936000000BTO
质押情况:0 BTO for time
0 BTO for space
输入以下命令可查看核实账户信息
【执行结果】
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli account get --account wangdenghui
Account: wangdenghui
Balance: 800.00000000 BTO
Pubkey: 049b98b5f5eea7fd5145842d08f8cd25052f69e731f9f550ac8a2e37792e165cf13fbc52ad7dad32eaa192799601b4cc35eab1923e007048f9d47c80aa4bf9cb8d
StakedBalance: 0.00000000 BTO
UnStakingBalance: 0.00000000 BTO
StakedSpaceBalance: 100.00000000 BTO
StakedTimeBalance: 100.00000000 BTO
UnStakingTimestamp: 0
AvailableSpaceBalance: 151142400440
UsedSpaceBalance: 360
AvailableTimeBalance: 28800000242
UsedTimeBalance: 158
UnClaimedReward: 0.00000000 BTO
Vote: N/A
Contracts: N/A
【方法提醒】
如果已把bcli复制到系统bin文件夹,则直接执行bcli ...,如果是复制到工作目录,则需要输入./bcli格式。 辉哥选择了第2种。
(1)复制bcli命令到本地工程目录
cp /home/duncanwang/go/src/github.com/bottos/bcli .
(2)复制到可执行文件夹:
cp /home/duncanwang/go/src/github.com/bottos/bcli /usr/bin/.
2.2 需求描述和智能合约代码分析
2.2.1 智能合约代码
(1)testRegUser.hpp
#define USER_NAME_LEN (20)
#define USER_INFO_LEN (20)
extern "C" {
int reguser();
}
//@abi action reguser
struct UserInfo {
char userName[USER_NAME_LEN];
char userInfo[USER_INFO_LEN];
};
//@abi table userinfo:[index_type:string, key_names:userName, key_types:string]
struct UserBaseInfo {
char userInfo[USER_INFO_LEN];
};
(2)testRegUser.cpp
#include "contractcomm.hpp"
#include "testRegUser.hpp"
#define PARAM_MAX_LEN (2048)
#define ERROR_PACK_FAIL (1)
#define ERROR_UNPACK_FAIL (2)
#define ERROR_SAVE_DB_FAIL (3)
static bool unpack_struct(MsgPackCtx *ctx, UserInfo *info)
{
uint32_t size = 0;
UNPACK_ARRAY(2)
UNPACK_STR(info, userName, (USER_NAME_LEN+1))
UNPACK_STR(info, userInfo, (USER_INFO_LEN+1))
return true;
}
static bool pack_struct(MsgPackCtx *ctx, UserBaseInfo *info)
{
PACK_ARRAY16(1)
PACK_STR16(info, userInfo )
return true;
}
int reguser()
{
UserInfo userinfo = {{0}};
if ( !parseParam<UserInfo>(userinfo) ) return ERROR_UNPACK_FAIL;
myprints(userinfo.userName);
myprints(userinfo.userInfo);
UserBaseInfo userBaseInfo = {{0}};
strcpy(userBaseInfo.userInfo, userinfo.userInfo);
char tablename[] = "userinfo";
if (!saveData(userBaseInfo, tablename, userinfo.userName)) return ERROR_SAVE_DB_FAIL;
return 0;
}
2.2.2 前端代码
(3) index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=375px, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Bottos Demo</title>
<script src="http://unpkg.com/bottos-sdk-js"></script>
<script src="./index.js"></script>
</head>
<body>
<div style="margin-top:50px">
<button style="width:100px;height:30px;background-color:bisque" onClick="getTransaction()" >查询合约结果</button>
<button style="width:100px;height:30px;background-color:coral" onClick="pushTransaction()">运行合约</button>
<button style="width:100px;height:30px;background-color:coral" onClick="createAccount()">创建账户</button>
</div>
<div style="margin-top:100px">
<p>创建账户执行结果</p>
<div id="createAccount" style="min-height:150px;background-color:#ccc">
</div>
<p>运行合约执行结果</p>
<div id="pushTransaction" style="min-height:150px;background-color:#ccc">
</div>
<p>查询合约执行结果</p>
<div id="getTransaction" style="min-height:150px;background-color:#ccc">
</div>
</div>
</body>
</html>
(4)index.js
var BottosWalletSDK = window.BottosWalletSDK
/* 此处更改为要调用的节点或者本地节点的IP地址 */
/*
const config = {
baseUrl:'http://42.159.154.130:8689/v1',
}
*/
const config = {
baseUrl:'http://192.168.1.105:8689/v1',
}
var SDK = new BottosWalletSDK(config)
var Tool = SDK.Tool
var Wallet = SDK.Wallet
var Contract = SDK.Contract
var Api = SDK.Api
/* 创建密钥对 */
const keys = Wallet.createKeys()
console.log({privateKey:keys.publicKey})
let account = 'testaccount'
let password = 'TestPassword1'/* 账号要求为至少有一个大小写,长度为6~20。2月底版本修改 */
let keystore = null
let publicKey = keys.publicKey
/* 创建账号,目前必须有推荐人,还要有推荐人私钥,存在私钥泄露风险。 */
function createAccount(){
console.log("createAccount")
let params = {
account:account,
password:password,
publicKey:publicKey
}
let referrerInfo = {
account:"wangdenghui",
privateKey:"e78c1801ca06099552afa86ea2ca38bd12fc8e5a8e817c3211074ab652c66ddf"
}
Wallet.createAccountWithIntro(params,referrerInfo)
.then(response=>{
keystore = response
console.log({response})
document.getElementById('createAccount').innerHTML = JSON.stringify(response)
}).catch(error=>{
console.log({error})
document.getElementById('createAccount').innerHTML = JSON.stringify(error)
})
}
/* 调用合约,目前采用wangdenghui本地账号,存在私钥泄露可能 */
function callContract(){
let params = {
method:'reguser',
contract:'reguser@wangdenghui',
sender:"wangdenghui",
param:{
userName:'duncan2',
// userInfo:JSON.stringify({phone:'110120',age:18})
userInfo:'GreatMan'
}
}
let privateKeyStr = "e78c1801ca06099552afa86ea2ca38bd12fc8e5a8e817c3211074ab652c66ddf"
Contract.callContract(params,privateKeyStr)
.then(response=>{
console.log({response})
document.getElementById('pushTransaction').innerHTML = JSON.stringify(response)
}).catch(error=>{
console.log({error})
document.getElementById('pushTransaction').innerHTML = JSON.stringify(error)
})
}
function pushTransaction(){
console.log("pushTransaction")
callContract()
}
/* 获取交易记录 */
function getTransaction(){
console.log("getTransaction")
let url = config.baseUrl + '/common/query'
let params = {
contract:'reguser@wangdenghui',
object:'userinfo',
key:'duncan'
}
fetch(url,{
method:'POST',
body:JSON.stringify(params)
}).then(function(response){return response.json()})
.then(function(response){
document.getElementById('getTransaction').innerHTML = JSON.stringify(response)
}).catch(function(error){
document.getElementById('getTransaction').innerHTML = JSON.stringify(error)
})
}
2.2.3 配置代码
(5)package.json
{
"name": "testRegUser",
"version": "1.0.0",
"description": "my first DAPP on BOTTOS chain!",
"main": "",
"directories": {
"test": "test"
},
"scripts": {
"dev": "lite-server",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"lite-server": "^2.4.0"
}
}
完整的工程文件请加入辉哥的知识星球获取。
2.2.2 智能合约编译和部署
(1)编译产生WASM和wast文件
Web Assembly(WASM)就是一种中间代码(字节码)技术。突出的特点就是精简,加载时间短以及高速的执行模型。其他高级语言(C/C++等)编写的程序都可以编译成WASM格式的程序。这样的好处是WASM可以兼容运行所有用C/C++等高级语言编写的程序。
以Bottos虚拟机举例,首先由高级语言C/C++编写的智能合约,经过编译生成wast文件,再转换成wasm的字节码格式,再由虚拟机加载wasm字节码文件,解析其中的字节码,转换成对应的方法执行。
另外,wast/wasm可以相互转换,参考:https://github.com/WebAssembly/wabt
python ../gentool.py --type wasm --file testRegUser.cpp
【成功执行结果】
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ python ../gentool.py --type wasm --file testRegUser.cpp
../bin/clang -emit-llvm -O3 --std=c++14 --target=wasm32 -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -I ../lib -I . -c testRegUser.cpp -o ./tmpdir/build/testRegUser.cpp
In file included from testRegUser.cpp:1:
../lib/contractcomm.hpp:181:22: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings]
myprints("ERROR: Get my contract name failed.");
^
../lib/contractcomm.hpp:196:18: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings]
myprints("getBinValue failed!");
^
2 warnings generated.
../bin/llvm-link -o ./tmpdir/linked.bc ./tmpdir/build/*
../bin/llc --asm-verbose=false -o ./tmpdir/assembly.s ./tmpdir/linked.bc
../bin/s2wasm -o testRegUser.wast -s 16384 ./tmpdir/assembly.s
(2)编译产生ABI文件
python ../gentool.py --file testRegUser.hpp
【运行结果】
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ python ../gentool.py --file testRegUser.hpp
[ testRegUser.abi ] is generated. Please have a check.
(3)部署智能合约与ABI文件
bcli contract deploy --contract reguser --account wangdenghui --code testRegUser.wasm --abi testRegUser.abi
【成功执行结果】
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli contract deploy --contract reguser --account wangdenghui --code testRegUser.wasm --abi testRegUser.abi
TrxHash: 87c8f9506e28e7df808dd3b439095c8bfac38a91d27ac71fb9a7464964de3222
This transaction is sent. Please check its result by command : bcli transaction get --trxhash <hash>
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli transaction get --trxhash 87c8f9506e28e7df808dd3b439095c8bfac38a91d27ac71fb9a7464964de3222
{
"ResourceReceipt": {
"account_name": "wangdenghui",
"space_token_cost": 8720,
"time_token_cost": 100
},
"Transaction": {
"contract": "bottos",
"cursor_label": 356016816,
"cursor_num": 10090,
"lifetime": 1546846894,
"method": "deploycontract",
"param": {
"contract": "reguser",
"contract_abi": "7b0a09227479706573223a205b5d2c0a092273747275637473223a205b0a20202020202020202020202020207b0a202020202020202020202020202009226e616d65223a202255736572496e666f222c0a2020202020202020202020202020092262617365223a2022222c0a202020202020202020202020202009226669656c6473223a207b0a2020202020202020202020202020090922757365724e616d65223a2022737472696e67222c0a202020202020202020202020202009092275736572496e666f223a2022737472696e67220a20202020202020202020202020202020202020207d0a2020202020202020202020202020097d2c0a20202020202020202020202020207b0a202020202020202020202020202009226e616d65223a20225573657242617365496e666f222c0a2020202020202020202020202020092262617365223a2022222c0a202020202020202020202020202009226669656c6473223a207b0a202020202020202020202020202009092275736572496e666f223a2022737472696e67220a20202020202020202020202020202020202020207d0a2020202020202020202020202020097d0a202020202020205d2c0a0922616374696f6e73223a205b0a20202020202020202020202020207b0a20202020202020202020202020200922616374696f6e5f6e616d65223a202272656775736572222c0a2020202020202020202020202020092274797065223a202255736572496e666f220a20202020202020202020202020207d0a202020202020205d2c0a09227461626c6573223a205b0a20202020202020202020202020207b0a202020202020202020202020202009227461626c655f6e616d65223a202275736572696e666f222c0a20202020202020202020202020200922696e6465785f74797065223a2022737472696e67222c0a202020202020202020202020202009226b65795f6e616d6573223a20205b0a2020202020202020202020202020090922757365724e616d65220a202020202020202020202020202009205d2c0a202020202020202020202020202009226b65795f7479706573223a20205b0a2020202020202020202020202020090922737472696e67220a202020202020202020202020202009205d2c0a2020202020202020202020202020092274797065223a20225573657242617365496e666f220a20202020202020202020202020207d0a202020202020205d0a7d0a",
"contract_code": "0061736d0100000001290760027f7f0060067f7f7f7f7f7f017f60027f7f017f60037f7f7f017f6000006000017f60017f017f023c0403656e7608676574506172616d000203656e76066d656d736574000303656e76067072696e7473000003656e760b73657442696e56616c7565000103060504050603020404017000000503010001073503066d656d6f72790200077265677573657200051e5f474c4f42414c5f5f7375625f495f74657374526567557365722e63707000040a9f1805f202004100420037028c4041004200370294404100420037029c40410042003702a440410042003702ac40410041003602b440410041003602b840410041003602bc40410041003602c040410041003602c440410041003602c840410041003602cc40410041003602d040410041003602d440410041003602d840410041003602dc40410041003602e040410041003602e440410041003602e840410041003602ec40410041003602f040410041003602f440410041003602f840410041003602fc404100410036028041410041003602844141004100360288414100410036028c414100410036029041410041003602944141004100360298414100410036029c41410041003602a041410041003602a441410041003602a841410041003602ac41410041003602b041410041003602b441410041003602b841410041003602bc41410041003602c041410041003602c441410041003602c841410041003602cc41410041003602d041410041003602d4410bb70201077f4100410028020441d0006b220636020441002102200641286a4100412810011a02400240200641286a1006450d00024020062d0028450d00200641286a4101722100410021050340200020056a2103200541016a2202210520032d00000d000b0b200641286a200210022006413c6a21004100210541002104024020062d003c450d002006413d6a2101410021030340200120036a2102200341016a2204210320022d00000d000b0b200020041002200641206a4100360200200641186a4200370300200642003703100340200641106a20056a200020056a2d000022033a0000200541016a210520030d000b2006410c6a41002d0088453a0000200641002900804537020441004103200641106a200641046a200641286a10071b21050c010b410221050b4100200641d0006a36020420050bc30401057f4100410028020441a0106b220536020441002104200541106a410041801010011a200541106a41801010002102200541003a0000200520023602082005410036020c2005200541106a3602040240200520054190106a1008450d0002400240024020052d0090104106470d00410021042005280298104102470d03200520054190106a1008450d0320052d0090104105470d01200528029810220141016a4116490d02200541013a00000c030b200541063a00000c020b200541063a00000c010b0240024020052802042203450d002005410c6a280200220220016a200541086a2802004d0d010b200541043a00000c010b02402001450d00200320026a210420002102200121030340200220042d00003a0000200241016a2102200441016a21042003417f6a22030d000b2005410c6a28020021020b41002104200020016a41003a00002005410c6a200220016a360200200520054190106a1008450d000240024020052d0090104105470d00200528029810220141016a4116490d01200541013a0000410021040c020b200541063a00000c010b0240024020052802042203450d002005410c6a280200220220016a200541086a2802004d0d010b200541043a0000410021040c010b02402001450d00200041146a2104200320026a2102200121030340200420022d00003a0000200441016a2104200241016a21022003417f6a22030d000b2005410c6a28020021020b2005410c6a200220016a360200200020016a41146a41003a0000410121040b4100200541a0106a36020420040bb60401077f410041002802044190106b220936020441002107200941106a410041801010011a200941013a0012200941dc013b0110024020002d00002203450d00200041016a2104410021060340200420066a2105200641016a2207210620052d00000d000b0b200941da013a0013200920073a001520092007410874418080fc07714110763a001402400240024002400240200741ffff03712206450d00200641066a22084180104d0d0141002106200941086a4100280098453602002009410029009045370200200941017221070340200720066a2105200641016a2204210620052d00000d000b2009200410020c030b410621080c010b200920033a001620064101460d00410120066b2107200041016a2106200941106a41077221050340200520062d00003a0000200541016a2105200641016a2106200741016a22070d000b0b4100210741002104024020012d0000450d00200141016a2100410021060340200020066a2105200641016a2204210620052d00000d000b0b024020022d0000450d00200241016a2100410021060340200020066a2105200641016a2207210620052d00000d000b0b410121062001200420022007200941106a200810030d01410021062009410e6a41002d00ae453a00002009410c6a41002f00ac453b0100200941086a41002800a845360200200941002900a045370200200941017221070340200720066a2105200641016a2204210620052d00000d000b2009200410020b410021060b410020094190106a36020420060bf20902047f017e0240024020002802042202450d00200028020c220341016a220420002802084d0d010b200041023a000041000f0b200220036a2d000021022000410c6a200436020002400240024002400240024002400240024002400240024002400240200241bb7e6a220241174b0d00024020020e18000101010101010203040501010101010101010101060107000b200141003a00000240200041046a2802002202450d002000410c6a2203280200220441026a2205200041086a2802004d0d080b200041073a000041000f0b200041063a000041000f0b200141013a00000240200041046a2802002202450d002000410c6a2203280200220441016a200041086a2802004d0d070b200041043a000041000f0b200141023a00000240200041046a2802002202450d002000410c6a2203280200220441026a200041086a2802004d0d070b200041043a000041000f0b200141033a00000240200041046a2802002202450d002000410c6a2203280200220441046a200041086a2802004d0d070b200041043a000041000f0b200141043a00000240200041046a2802002202450d002000410c6a2203280200220441086a200041086a2802004d0d070b200041043a000041000f0b200141053a00000240200041046a2802002202450d002000410c6a2203280200220441026a2205200041086a2802004d0d070b200041043a000041000f0b200141063a00000240200041046a2802002202450d002000410c6a2203280200220441026a2205200041086a2802004d0d070b200041043a000041000f0b200220046a22002d0000210220002d0001210020032005360200200141086a200220004108747222004118742000410874418080fc07717241107636020041010f0b200141086a200220046a2d00003a00002003200328020041016a36020041010f0b200141086a2200200220046a22022d00003a0000200141096a20022d00013a00002003200328020041026a360200200020002f010022014118742001410874418080fc0771724110763b010041010f0b200141086a2205200220046a22002d00003a0000200141096a20002d00013a00002001410a6a200041026a2d00003a00002001410b6a200041036a2d00003a00002003200328020041046a3602002005200528020022004118742000410874418080fc07717220004108764180fe03712000411876727236020041010f0b200141086a2205200220046a22002d00003a0000200141096a20002d00013a00002001410a6a200041026a2d00003a00002001410b6a200041036a2d00003a00002001410c6a200041046a2d00003a00002001410d6a200041056a2d00003a00002001410e6a200041066a2d00003a00002001410f6a200041076a2d00003a00002003200328020041086a360200200520052903002206423886200642288642808080808080c0ff0083842006421886428080808080e03f8320064208864280808080f01f838484200642088842808080f80f832006421888428080fc07838420064228884280fe0383200642388884848437030041010f0b200220046a22002d0000210220002d0001210020032005360200200141086a200220004108747222004118742000410874418080fc07717241107636020041010f0b200220046a22002d0000210220002d0001210020032005360200200141086a200220004108747222004118742000410874418080fc07717241107636020041010b0b43040041040b04b0620000004180c5000b0975736572696e666f00004190c5000b0c7061636b206661696c6564000041a0c5000b0f73617665206462206661696c656400",
"vm_type": 1,
"vm_version": 1
},
"sender": "wangdenghui",
"sig_alg": 1,
"signature": "8b7732622a45a0637eb2783bd785b038e2e3ba2662856588f7813c1725b021315e53b2a318d5b09bcdf9a7c6bd0e1fab264a8a954a922c4de90d4514c9fab9bf",
"version": 65536
},
"TrxHash": "87c8f9506e28e7df808dd3b439095c8bfac38a91d27ac71fb9a7464964de3222"
}
<<<Transaction Status>>> : commited
(4)运行合约
bcli transaction push --sender wangdenghui --method reguser --contract reguser@wangdenghui --param "userName:duncan, userInfo:GoodMan"
【执行成功结果】
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli transaction push --sender wangdenghui --method reguser --contract reguser@wangdenghui --param "userName:duncan, userInfo:GoodMan"
0 : {userName string} , KEY: userName , VAL: duncan
1 : {userInfo string} , KEY: userInfo , VAL: GoodMan
TrxHash: 95872bc215ec1afabb937536c0f71e5d4db704b518d9039bba67aba0538f96a9
This transaction is sent. Please check its result by command : bcli transaction get --trxhash <hash>
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli transaction get --trxhash 95872bc215ec1afabb937536c0f71e5d4db704b518d9039bba67aba0538f96a9
{
"ResourceReceipt": {
"account_name": "wangdenghui",
"space_token_cost": 187,
"time_token_cost": 165
},
"Transaction": {
"contract": "reguser@wangdenghui",
"cursor_label": 1180986307,
"cursor_num": 10163,
"lifetime": 1546847113,
"method": "reguser",
"param": {
"userinfo": "GoodMan",
"username": "duncan"
},
"sender": "wangdenghui",
"sig_alg": 1,
"signature": "fd21d873ba0cd0a8cf6ba5f756562eae5ae93354642bc52c7739c2bd1e80550f35bbb8278b106af39fdc2c0c46e72468675aeb071cb3600e5ecd39b9fcbb3d22",
"version": 65536
},
"TrxHash": "95872bc215ec1afabb937536c0f71e5d4db704b518d9039bba67aba0538f96a9"
}
<<<Transaction Status>>> : commited
界面截图:
2.运行合约.png
(5) 查看执行结果
合约正确执行后,则保存至链上的数据userinfo和username分别是GoodMan和duncan,可以通过bcli gettable 命令进行查询,该命令成功后将返回BCLI发送的Transaction信息。
参数说明:
--contract 合约账户名 reguser@wangdenghui
--table 要向链上查询的TABLE名 (参考ABI文件TABLE描述)
--key 要向链上查询的key关键字的值,是关键字的值
bcli gettable --contract reguser@wangdenghui --table userinfo --key duncan
【成功结果】
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli gettable --contract reguser@wangdenghui --table userinfo --key duncan
{
"contract": "reguser@wangdenghui",
"object": "userinfo",
"key": "duncan",
"value": "dc0001da0007476f6f644d616e"
}
Table data is :map[userinfo:GoodMan]
【错误执行结果】-部署参数错误
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli gettable --contract register@wangdenghui --table userreginfo --key userName
BCliGetTableInfo error:
errcode:10205 msg:"query object: object not found"
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli gettable --contract register@wangdenghui --table userinfo --key userreginfo
BCliGetTableInfo error:
errcode:10205 msg:"query object: object not found"
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli gettable --contract register@wangdenghui --table userreginfo --key duncanwang
BCliGetTableInfo error:
errcode:10205 msg:"query object: object not found"
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli gettable --contract register@wangdenghui --table userreginfo --key userinfo.userName
BCliGetTableInfo error:
errcode:10205 msg:"query object: object not found"
【原因分析】
if (!saveData(userBaseInfo, tablename, userinfo.userName)) return ERROR_SAVE_DB_FAIL;
table的名为testRegUser.abi字"userinfo",查找关键字为:"table_name": "userinfo";key的内容为第3个参数的实际值,就是下面命令的userName:duncan值。
bcli transaction push --sender wangdenghui --method reguser --contract reguser@wangdenghui --param "userName:duncan, userInfo:GoodMan"
2.3 NVN和NPM安装
(1)安装NVM
NVM(Node Version Manager,Node多版本管理器),是一个可以让你在同一台机器上安装和切换不同版本node的工具。
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
【成功结果】
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/contact$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 12819 100 12819 0 0 1976 0 0:00:06 0:00:06 --:--:-- 3235
=> Downloading nvm from git to '/home/duncanwang/.nvm'
=> Cloning into '/home/duncanwang/.nvm'...
remote: Enumerating objects: 267, done.
remote: Counting objects: 100% (267/267), done.
remote: Compressing objects: 100% (242/242), done.
remote: Total 267 (delta 31), reused 86 (delta 15), pack-reused 0
Receiving objects: 100% (267/267), 119.47 KiB | 236.00 KiB/s, done.
Resolving deltas: 100% (31/31), done.
=> Compressing and cleaning up git repository
=> Appending nvm source string to /home/duncanwang/.bashrc
=> Appending bash_completion source string to /home/duncanwang/.bashrc
=> Close and reopen your terminal to start using nvm or run the following to use it now:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
(2)重启系统或者重新读入初始化文件
source:使当前shell读入路径为filepath的shell文件并依次执行文件中的所有语句,通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。
source ~/.bashrc
(3)nvm install安装NODE.JS版本
nvm ls-remote可查看node所有版本,然后选择安装
【执行结果】
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/contact$ nvm install 8.15.0
Downloading and installing node v8.15.0...
Downloading https://nodejs.org/dist/v8.15.0/node-v8.15.0-linux-x64.tar.xz...
######################################################################################################################################################################################## 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v8.15.0 (npm v6.4.1)
Creating default alias: default -> 8.15.0 (-> v8.15.0)
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/contact$ node -v
v8.15.0
(4)安装bottos-sdk-js
npm install bottos-sdk-js --save
【成功执行结果】
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/contact$ npm install bottos-sdk-js --save
> secp256k1@2.0.4 install /home/duncanwang/go/work/contract-tool-cpp/contact/node_modules/eccrypto/node_modules/secp256k1
> npm run rebuild
> secp256k1@2.0.4 rebuild /home/duncanwang/go/work/contract-tool-cpp/contact/node_modules/eccrypto/node_modules/secp256k1
> node-gyp rebuild
...
make: Leaving directory '/home/duncanwang/go/work/contract-tool-cpp/contact/node_modules/secp256k1/build'
> protobufjs@6.8.8 postinstall /home/duncanwang/go/work/contract-tool-cpp/contact/node_modules/protobufjs
> node scripts/postinstall
npm WARN saveError ENOENT: no such file or directory, open '/home/duncanwang/go/work/contract-tool-cpp/contact/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/home/duncanwang/go/work/contract-tool-cpp/contact/package.json'
npm WARN contact No description
npm WARN contact No repository field.
npm WARN contact No README data
npm WARN contact No license field.
+ bottos-sdk-js@0.5.0
added 58 packages from 74 contributors and audited 185 packages in 82.779s
found 0 vulnerabilities
(5)安装并启动 lite-server
【定义】lite-server 是轻量级的,仅适用于开发 的 node 服务器, 它仅支持 web app。 它能够为你打开浏览器, 当你的html或是JavaScript文件变化时,它会识别到并自动帮你刷新浏览器, 还能使用套接字自动注入变化的CSS, 当路由没有被找到时,它将自动后退页面。
1)安装lite-server
npm install lite-server --save-dev
【结果】
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ npm install lite-server --save-dev
npm WARN testRegUser@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
+ lite-server@2.4.0
added 345 packages from 274 contributors, removed 55 packages and audited 2607 packages in 31.781s
found 0 vulnerabilities
2)启动lite-server
npm run dev
【结果】
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ npm run dev
> testRegUser@1.0.0 dev /home/duncanwang/go/work/contract-tool-cpp/testRegUser
> lite-server
Did not detect a `bs-config.json` or `bs-config.js` override file. Using lite-server defaults...
** browser-sync config **
{ injectChanges: false,
files: [ './**/*.{html,htm,css,js}' ],
watchOptions: { ignored: 'node_modules' },
server: { baseDir: './', middleware: [ [Function], [Function] ] } }
[Browsersync] Access URLs:
-------------------------------------
Local: http://localhost:3000
External: http://10.225.18.68:3000
-------------------------------------
UI: http://localhost:3001
UI External: http://localhost:3001
-------------------------------------
[Browsersync] Serving files from: ./
[Browsersync] Watching files...
[Browsersync] Couldn't open browser (if you are using BrowserSync in a headless environment, you might want to set the open option to false)
2.4 DAPP界面操作
(1) 本地windows上运行网页
本地windwos的chrome浏览器上运行网页,例如虚拟机 服务器地址:http://10.225.18.68:3000/
(2)点击 查询合约 结果按钮
查询合约不需要账户信息,只要输入http网址即可查询到合约内容。
查看可知同CLI命令查询的结果。
{"errcode":0,"msg":"success","result":{"contract":"reguser@wangdenghui","object":"userinfo","key":"duncan","value":"dc0001da0007476f6f644d616e"}}
截图:
3.查询合约结果.png
(3)点击 运行合约
输出结果:
{"errcode":0,"msg":"success","result":{"trx":{"version":65536,"cursor_num":7934,"cursor_label":773838136,"lifetime":1548324372,"sender":"wangdenghui","contract":"reguser@wangdenghui","method":"reguser","param":"dc0002da000764756e63616e32da000847726561744d616e","sig_alg":1,"signature":"666e849512b77ef2c46daca204ad6e51b23ecd78698e75ffa3d65afeb3f24ea16a6b533a2ab38e4dae46bb853a6a3d458aabe7776d5134cbc7a055a06b6c4de3"},"trx_hash":"b56eaf25b2ac1ff81e547f8efb87d5ef1423afec1dbdd9a8af75ad4e2dd0de61"}}
在命令行下查询结果,发现该交易执行是成功的。
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli transaction get --trxhash b56eaf25b2ac1ff81e547f8efb87d5ef1423afec1dbdd9a8af75ad4e2dd0de61
{
"ResourceReceipt": {
"account_name": "wangdenghui",
"space_token_cost": 190,
"time_token_cost": 376
},
"Transaction": {
"contract": "reguser@wangdenghui",
"cursor_label": 773838136,
"cursor_num": 7934,
"lifetime": 1548324372,
"method": "reguser",
"param": {
"userinfo": "GreatMan",
"username": "duncan2"
},
"sender": "wangdenghui",
"sig_alg": 1,
"signature": "666e849512b77ef2c46daca204ad6e51b23ecd78698e75ffa3d65afeb3f24ea16a6b533a2ab38e4dae46bb853a6a3d458aabe7776d5134cbc7a055a06b6c4de3",
"version": 65536
},
"TrxHash": "b56eaf25b2ac1ff81e547f8efb87d5ef1423afec1dbdd9a8af75ad4e2dd0de61"
}
<<<Transaction Status>>> : commited
【说明】目前BOTTOS智能合约还不支持复杂结构体的数据存链动作。
(8) BOTTOS创建账户
目前机制下,BOTTOS账户创建成功后,如果要用于部署合约,还需要质押一定的TOKEN。所以只演示创建账号而已。
创建账户执行结果-成功
{"errcode":0,"msg":"success","result":{"trx":{"version":65536,"cursor_num":5873,"cursor_label":1210352703,"lifetime":1548318177,"sender":"wangdenghui","contract":"bottos","method":"newaccount","param":"dc0002da000b746573746163636f756e74da008230346636373733333833363437636236613461393162663134396462656430393935633931376533323637336435313132393331613466663538663335343630663838313137366665383065373933663533363037613736643034643764393638323965376562643061626530656139646331363061313366343435366461656131","sig_alg":1,"signature":"176c4b0e86073050201a7da745ba95c193ac694b29145c5be46abcc43f9cc8861b7f99005b103624457acd597059618f909db158b59ba2042d9e3b7291b5739a"},"trx_hash":"760b5c19fc716ce980d9a6180e82e1942e237b8eb76a70e8925fefb452530ca9"}}
截图:
2.运行合约.png
命令行查看,可以看到该账号。该账号可以跟创建的钱包关联起来,也可以不用关联起来,它会一直存在网上。
./bcli account get --account testaccount
duncanwang@ubuntu64bit-server:~/go/src/github.com/bottos$ ./bcli account get --account testaccount
Account: testaccount
Balance: 0.00000000 BTO
Pubkey: 04f6773383647cb6a4a91bf149dbed0995c917e32673d5112931a4ff58f35460f881176fe80e793f53607a76d04d7d96829e7ebd0abe0ea9dc160a13f4456daea1
StakedBalance: 0.00000000 BTO
UnStakingBalance: 0.00000000 BTO
StakedSpaceBalance: 0.00000000 BTO
StakedTimeBalance: 0.00000000 BTO
UnStakingTimestamp: 0
AvailableSpaceBalance: 0
UsedSpaceBalance: 0
AvailableTimeBalance: 0
UsedTimeBalance: 0
UnClaimedReward: 0.00000000 BTO
Vote: N/A
Contracts: N/A
常见错误-端口链接拒绝
【错误提示】
输入网址http://192.168.1.105:3000/链接主页,采用chrome的检查模式,发现以下错误:
http://192.168.1.108:8689/v1/block/height net::ERR_CONNECTION_REFUSED
【分析】
duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ netstat -nltp
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:8689 0.0.0.0:* LISTEN 22034/./bottos
tcp 0 0 127.0.0.1:6869 0.0.0.0:* LISTEN 22034/./bottos
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:6870 0.0.0.0:* LISTEN 22034/./bottos
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp6 0 0 :::9868 :::* LISTEN 22034/./bottos
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 :::3000 :::* LISTEN 23004/lite-server
tcp6 0 0 :::3001 :::* LISTEN 23004/lite-server
以上代码表示8689只能被127.0.0.1调用。修改 config.toml,把localhost改为0.0.0.0,就不会有这个错误了。
[Rest]
RESTPort = 8689
RESTHost = "0.0.0.0"
[Plugin.Wallet]
WalletDir = ""
WalletRESTPort = 6869
WalletRESTHost = "0.0.0.0"
3,参考
1)使用C++编写智能合约
2)DApp开发与调试(JavaScript版本)
3)API Document
4)bottos-sdk-js API Document
5) linux查看和修改PATH环境变量的方法