HiBlock区块链社区区块链入门

铂链第5课 如何在BOTTOS上搭建第一个DAPP应用[C++程

2019-01-24  本文已影响5人  笔名辉哥

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环境变量的方法

上一篇下一篇

猜你喜欢

热点阅读