合约部署调用演示

本文旨在让用户可以快速便捷地搭建PlatONE区块链以体验其功能,用户可以根据如下步骤快速搭建一条区块链,并在链上部署合约、调用合约。

1. 搭建区块链

1.1 依赖环境

1.2 PlatONE源码下载及编译

首先用户需要从github下载PlatONE源码并编译

# 获取PlatONE源码
git clone --recursive https://github.com/PlatONEnterprise/PlatONE-Go.git
export WORKSPACE=${PWD}/PlatONE-Go/release/linux

# 编译PlatONE
cd PlatONE-Go; make all; cd ..

如果编译失败. 请确保你安装了 1.1中全部软件. 然后重新尝试.

1.3 快速搭链

PlatONE提供了便捷的搭链脚本,用户可以使用脚本platonectl.sh快速在本机搭建出单节点或四节点的区块链。

搭链成功后,会在${WORKSPACE}/data目录下生成节点的数据文件,可以观察日志文件以查看节点的运行情况,比如node-0节点日志位于目录${WORKSPACE}/data/node-0/logs/platone_log/中。

2. PlatONE账户

2.1 创建PlatONE账户

在发布交易之前,首先用户需要创建一个账户。

cd ${WORKSPACE}/../../cmd/SysContracts/

./script/create_accout.sh --ip 127.0.0.1 --rpc_port 6791

该命令会创建一个新的账户,创建时需要输入一个账户密码,方便后续解锁。 运行结果如下,账户地址记录在./config.json文件中:

nodeid: 127.0.0.1
rpc_port: 6791

###########################################
####       Create an account           ####
###########################################

Input account passphrase.
passphrase: your_phrase
--output{"jsonrpc":"2.0","id":1,"result":"0x08e7988e60ab5aa49d1f7aa9435ac91b9fcf772c"} --output
New account: 0x08e7988e60ab5aa49d1f7aa9435ac91b9fcf772c
{"jsonrpc":"2.0","id":1,"result":true}
127.0.0.1:6791

 Create config.json for contract-deploy

{
  "url":"http://127.0.0.1:6791",
  "gas":"0x0",
  "gasPrice":"0x0",
  "from":"0x08e7988e60ab5aa49d1f7aa9435ac91b9fcf772c"
}

2.2 解锁账户

首次创建账户或者是长时间没用使用账户发送过交易,账户会被锁定,不能发送交易。需要使用如下命令,重新为账户解锁。

cd ${WORKSPACE}/../../cmd/SysContracts/
./script/unlock_account.sh \
            --account 0x08e7988e60ab5aa49d1f7aa9435ac91b9fcf772c \
            --phrase "your_phrase" \
            --ip 127.0.0.1 \
            --rpc_port 6791

3. 部署调用合约

3.1 创建并编译用户合约

首先通过如下命令创建一个默认合约,该合约包含了两个基本方法setNamegetName,用户可以在此基础上编写合约逻辑。

cd ${WORKSPACE}/../../cmd/SysContracts/
# 创建默认合约
./script/autoprojectForApp.sh  . my_contract

# 编译合约
./script/autoprojectForApp.sh  .

生成的合约源码文件位于${WORKSPACE}/../../cmd/SysContracts/appContract/my_contract/my_contract.cpp

my_contract.cpp:(新增)

#include <stdlib.h>
#include <string.h>
#include <string>
#include <bcwasm/bcwasm.hpp>

namespace demo {
class my_contract : public bcwasm::Contract
{
    public:
    my_contract(){}

    /// parent class implementation: bcwasm:: virtual function of Contract
    /// this function is called only once when the contract is first released
    void init()
    {
        bcwasm::println("init success...");
    }
    /// define event.
    BCWASM_EVENT(Notify, uint64_t, const char *)

    public:
    void setName(const char *msg)
    {
        // define state
        bcwasm::setState("NAME_KEY", std::string(msg));
        // return event
        BCWASM_EMIT_EVENT(Notify, 0, "Set Name.");
    }
    const char* getName() const
    {
        std::string value;
        bcwasm::getState("NAME_KEY", value);
        // read contract data and return
        return value.c_str();
    }
};
}
// the function below will generate an ABI file for external calls
BCWASM_ABI(demo::my_contract, invokeNotify)
BCWASM_ABI(demo::my_contract, getName)

3.2 部署合约

PlatONE提供了合约工具ctool,可以使用该工具来部署智能合约及发送交易。

cd ${WORKSPACE}/../../cmd/SysContracts/build

# ctool是用来部署合约及发送交易的工具
cp ${WORKSPACE}/bin/ctool .  

# 部署合约
./ctool deploy --abi appContract/my_contract/my_contract.cpp.abi.json --code appContract/my_contract/my_contract.wasm --config ../config.json

结果:

trasaction hash: 0x2f3a868d8ceb60804a830e5fc35611e3ae22ccb6ef298830acd84aba41f6dd99
contract address: 0x2ee8d0545ebd20f9a992ff54cb0f21a153539206

3.3 调用合约

调用合约的setName方法

./ctool invoke --addr 0x2ee8d0545ebd20f9a992ff54cb0f21a153539206 --abi appContract/my_contract/my_contract.cpp.abi.json   --config ../config.json  --func "setName" --param "wxbc"  

 request json data:[{"from":"0x32ab0a20b589f40c7e3d6ee485a2404bb7269f87","to":"0x2ee8d0545ebd20f9a992ff54cb0f21a153539206","gas":"0x0","gasPrice":"0x0","value":"","data":"0xdb8800000000000000028c696e766f6b654e6f746966798477786263","txType":2}]

 response json:{"jsonrpc":"2.0","id":1,"result":"0xeb3680c65b393952a07ec590cef7b19fc87877a9fbb70c8e16797a97ed4cfaeb"}

调用合约的getName方法:

./ctool invoke --addr 0x2ee8d0545ebd20f9a992ff54cb0f21a153539206 --abi appContract/my_contract/my_contract.cpp.abi.json   --config ../config.json  --func getName

request json data:[{"from":"0x32ab0a20b589f40c7e3d6ee485a2404bb7269f87","to":"0x2ee8d0545ebd20f9a992ff54cb0f21a153539206","gas":"0x0","gasPrice":"0x0","value":"","data":"0xd1880000000000000002876765744e616d65","txType":2},"latest"]

response json:{"jsonrpc":"2.0","id":1,"result":"0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000047778626300000000000000000000000000000000000000000000000000000000"}

result: wxbc

4. 交易查询

4.1 通过控制台连接到节点

可通过以下方式进入PlatONE控制台与链进行交互。

cd  ${WORKSPACE}/bin

./platone attach http://127.0.0.1:6791

命令执行的结果如下:

Welcome to the PlatONE JavaScript console!

instance: PlatONEnetwork/platone/v0.2.0-stable-1b13ff73/linux-amd64/go1.12.4
coinbase: 0x938c231429f5ab34244618fe0dc7380e319b470e
at block: 1557 (Tue,18 Jun 2019 16:29:12 CST)
 datadir: /home/user/PlatONE-Workspace/chain/PlatONE_linux/data/node-1
 modules: admin:1.0 eth:1.0 net:1.0 personal:1.0 rpc:1.0 web3:1.0

>

4.2 查询交易receipt

> eth.getTransactionReceipt("0x2f3a868d8ceb60804a830e5fc35611e3ae22ccb6ef298830acd84aba41f6dd99")

结果如下:

{
  blockHash: "0x3f1e326f4b122efb26e9da417daff97dbb403c714d3324e8020ddce04b88617a",
  blockNumber: 236,
  contractAddress: "0x2ee8d0545ebd20f9a992ff54cb0f21a153539206",
  cumulativeGasUsed: 1996535,
  from: "0x32ab0a20b589f40c7e3d6ee485a2404bb7269f87",
  gasUsed: 1996535,
  logs: [],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  status: "0x1",
  to: null,
  transactionHash: "0x2f3a868d8ceb60804a830e5fc35611e3ae22ccb6ef298830acd84aba41f6dd99",
  transactionIndex: 0
}

5. 停止节点并清除数据

cd ${WORKSPACE}/scripts
./platonectl.sh stop -n 0
./platonectl.sh clear -n 0