本文首先通过示例(Hello World)来说明普通 wasm 合约的编写、编译过程,然后简单介绍关于构建静态库的方法。
在编写C++合约时,平台在接口名称的命名上有一些限制,具体可参见接口名称限制说明。
普通 wasm 合约
创建一个临时目录,用于存放编写的合约,例如
/tmp/bob
。mkdir /tmp/bob cd /tmp/bob
创建一个
hello.cpp
文件,即合约代码文件。touch hello.cpp
编辑
hello.cpp
,引入需要的头文件。#include <mychainlib/contract.h>
mychainlib/contract.h
中包含编写合约所需的数据结构和 C++ API。使用如下方式编写合约:
#include <mychainlib/contract.h> using namespace mychain; class hello:public Contract { public: INTERFACE void hi(const std::string& user ) { Log("hi"s, {"ok", user}); } }; INTERFACE_EXPORT(hello, (hi))
在完成合约编写后,执行以下命令编译合约:
说明假设合约文件的名称是
xxx.cpp
,则执行命令my++ -o xxx.wasm xxx.cpp
。my++ -o hello.wasm hello.cpp
如果命令执行成功,您将在
/tmp/bob
目录下看到以下三个文件:hello.wasm
:合约的 wasm 字节码文件hello.abi
:合约的 ABI 定义文件hello.wasc
:合并字节码和 ABI 的文件,在部署合约时,交易中的code
字段就是该文件内容。执行编译命令时,如果使用
-o
选项指定的文件名不是以 .wasm 结尾,那么产生的 ABI 文件就是-o
指定的文件名后面直接加 .abi。例如,执行编译命令:
my++ -o abc hello.cpp
会产生名为
abc.wasc
的字节码文件和名为abc.abi
的 ABI 定义文件。说明ABI文件的格式定义请参见ABI定义。
my++ 也可以同时编译多个源文件。例如您可以在
contract.cpp
中定义合约,在utils.cpp
中定义一些工具函数,则编译命令为:$ my++ contract.cpp utils.cpp -o contract.wasm
构建静态库
您可以使用 MYCDT 提供的工具,将一组源文件编译打包成一个 wasm 的静态库,提供给合约使用。
例如,您已编写了两个 C++ 源文件 foo.cc
和 bar.cc
,并且分别定义了一些工具函数,则函数接口统一声明在头文件 foobar.h
中。
├── bar.cc
├── foo.cc
└── foobar.h
用以下命令编译源代码,然后打包成一个静态库 foobar.a
。
$ my++ -c foo.cc bar.cc
$ llvm-ar rcs foobar.a foo.o bar.o
说明:my++ 可以一次编译单个或多个源文件。
如果您需要在合约内使用这个静态库,只需在合约代码中包含头文件 foobar.h
,然后编译合约时指定静态库路径即可。
$ my++ main.cc /path/to/foobar.a -o contract.wasc