- contract TradeOffer(assetRequested: Asset,
- amountRequested: Amount,
- seller: Program,' Z3 y9 C- T0 j" b6 d. [
- cancelKey: PublicKey) locks offered {
- clause trade() requires payment: amountRequested of assetRequested {! l/ N; t5 A. j3 m- U& s. b
- lock payment with seller
- unlock offered
- }
- clause cancel(sellerSig: Signature) {, T5 U- a5 U! `- {
- verify checkTxSig(cancelKey, sellerSig)* M( `4 U4 C/ I: ^9 y( _2 C9 {
- unlock offered
- }& W+ T. r- ]' x7 L
- }
导读: 初次接触比原只能合约的请点击比原智能合约入门 和 Equity 语言入门 学习,方便更好的理解该文档
锁定合约( |$ s1 A! \. g! m
第一步:调用create-account-receiver 生成 control_program" v/ R& M7 i" J; v0 j8 w0 K
0 o V- A2 c5 f4 h
以下是相关代码片段:
sendHttpPost("{\"account_id\":\"0IJVD7MNG0A02\"}","create-account-receiver","http://127.0.0.1:9888","");& D5 n3 |/ r& }+ n
第二步调用list-pubkeys 获取 pubkey
以下是相关代码片段:
sendHttpPost("{\"account_id\":\"0IJVD7MNG0A02\"}","list-pubkeys","http://127.0.0.1:9888","");
第三步: 将1 2步获取的值调用compile接口编译合约获得program 合约程序
- S( g2 F0 o( k- P, u
, G6 r9 Y' p' v$ \$ I* s( W
以下是相关代码片段:4 M; W- X- Z7 r: u
- JSONObject param=new JSONObject();
- JSONArray agrs=new JSONArray();
- //合约的四个参数值
- JSONObject assetParam=new JSONObject();2 H( _, N# P' U* G' Z! L( |
- assetParam.put("string","81d097312645696daea84b761d2898d950d8fba0de06c9267d8513b16663dd3a");
- agrs.put(assetParam);
- JSONObject amountParam=new JSONObject();' J( r! [' s4 G* L2 N
- amountParam.put("integer",200000000l);4 I( k7 q* {0 g. B$ F& R# G
- agrs.put(amountParam);
- JSONObject programParam=new JSONObject();
- programParam.put("string",control_program);
- agrs.put(programParam);5 V/ f, c/ }: U* w' f9 k9 V4 z
- JSONObject publicKeyParam=new JSONObject();
- publicKeyParam.put("string",pubkey);
- agrs.put(publicKeyParam);- y/ s8 B5 N& O0 o" h- Z C* v! ^
- param.put("agrs",agrs);
- param.put("contract","contract TradeOffer(assetRequested: Asset, amountRequested: Amount, seller: Program, cancelKey: PublicKey) locks offered { clause trade() requires payment: amountRequested of assetRequested { lock payment with seller unlock offered } clause cancel(sellerSig: Signature) { verify checkTxSig(cancelKey, sellerSig) unlock offered } }");7 h5 M: n3 J8 r9 A& p% P A4 d
- //调用编译合约* o& }7 F3 v4 |$ l) a- c
- sendHttpPost(param.toString(),"list-pubkeys","http://127.0.0.1:9888","");
第四步:将program 传入build-transaction接口去build一个交易的到data+ h" N0 z; {) D, @7 U' |8 v" [
以下是相关代码片段:
- param=new JSONObject();& I. Y4 V4 C# S
- agrs=new JSONArray();
- JSONObject spendAccount=new JSONObject();
- spendAccount.put("account_id","0H757LPD00A02");0 R9 b6 Z" P4 x2 b1 J6 s
- spendAccount.put("amount",9909099090000l);$ T7 b e4 E: s% S* n3 I2 T3 d
- spendAccount.put("asset_id","161b9767b664df907fa926a31f9e835236e57f3e9ccc5f80c12bd97723322652");
- spendAccount.put("type","spend_account");& V: P; O4 U# `3 F
- agrs.put(spendAccount);! T" a7 Z1 G2 ~' l4 f
- JSONObject controlAccount=new JSONObject();' A- s4 Y! m, t. X4 H9 T' [1 L( n
- controlAccount.put("control_program",program);
- controlAccount.put("amount",9909099090000l);
- controlAccount.put("asset_id","161b9767b664df907fa926a31f9e835236e57f3e9ccc5f80c12bd97723322652");) o% b+ r3 H1 R0 d+ ^ p7 Q f
- controlAccount.put("type","control_program");! [# d$ a4 H% E6 b: h o8 X Q4 k
- agrs.put(controlAccount);6 G3 |" O& F# f
- JSONObject spendAccount2=new JSONObject();
- spendAccount2.put("account_id","0H757LPD00A02");
- spendAccount2.put("amount",6000000l);
- spendAccount2.put("asset_id","ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
- spendAccount2.put("type","spend_account");# a& N& D* ^2 ?$ @
- agrs.put(spendAccount2);
- param.put("actions",agrs);
- param.put("ttl",0);
- sendHttpPost(param.toString(),"build-transaction","http://127.0.0.1:9888","");
第五步:输入密码调用sign-transaction签名第四步build的data 得到raw_transaction
以下是相关代码片段:
param=new JSONObject();
param.put("password","xxx");
param.put("transaction",data);
sendHttpPost(param.toString(),"sign-transaction","http://127.0.0.1:9888","");5 z( N( M% Y* s6 b0 [! N1 O
第六步:调用submit-transactions提交交易 Q3 k) c1 j8 V" y f h
% R: C! ?, W- x7 [3 s7 e7 S
以下是相关代码片段:" | s( X/ z' _' t
param=new JSONObject();+ M; R: i- e9 T5 V! j3 a, w
param.put("raw_transaction",raw_transaction);) h+ R" L* w) ^0 W
sendHttpPost(param.toString(),"submit-transactions","http://127.0.0.1:9888","");0 U1 y$ M9 Q' D$ v+ H' a
解锁/取消合约$ l: l/ `: Y7 ^! P- \" O
首先需要decode出生成合约时候的参数/ E: L, n) O) d; l7 X
调用list-unspent-outputs 获取生成的合约信息获取program% y: W" u1 ^1 i# a' y! r
以下是相关代码片段:
param=new JSONObject();
param.put("id",outputid);
param.put("smart_contract",true);9 h+ x" R4 P6 m/ Z. t3 i( r
sendHttpPost(param.toString(),"list-unspent-outputs","http://127.0.0.1:9888","");" n2 h# v0 E/ y5 z4 I
调用decode-program 传入获取生成的合约参数信息- d0 k* @5 T+ {+ h1 \, v0 z3 s7 h
$ C* Z! P2 P, S
以下是相关代码片段:0 _% l- Q6 S& s, o$ |" x
param=new JSONObject();
param.put("program",program);
sendHttpPost(param.toString(),"decode-program","http://127.0.0.1:9888","");
需要注意的是decode出来的为值是逆序的(后续会有文章详细介绍); R, V: H/ S% v9 V. \4 @
解锁/取消其实就是把生成合约的步骤中的第三步去掉,替换调用生成合约第四步的参数即可9 p6 n I, z6 v& I3 w' i
取消合约的构造参数如下:: k- b( z. x& {& A
3 z8 ]) D4 z) i5 ]! ]" [
- spendAccountUnspentOutput = arguments: [{. Y: X& D1 {( h* L
- type: 'raw_tx_signature',3 R0 w3 ]3 C; B. I
- // 生成合约第二步的pubkeylist 详情" H( ?$ y( n1 x- W2 | L
- raw_data: {
- derivation_path: pubkeylist.pubkey_infos[0].derivation_path,
- xpub: pubkeylist.root_xpub
- } |1 B2 j$ X; m' M, P" D6 d3 r
- }, {/ N2 h1 ]: X' m( X& i
- type: 'data',9 G1 N! [0 E+ L! I' }2 `
- raw_data: {! _! T* @( r: {$ V7 u6 L# M5 u# K! A
- // 参数偏移量 在一个合约里是固定的 ' \. J% q6 y6 u1 j% s2 I
- value: '13000000'; `+ [- D/ R; g# l
- }
- }], S$ s# e4 S7 R! F3 o: ~. a
- output_id: output_id,3 _* _2 ?: J0 e( @* G
- type: 'spend_account_unspent_output'
- }
- const controlAction = {0 x! ]/ u* }# n- F
- type: 'control_program',5 \* ?- X+ z4 _7 U4 ^6 B
- amount: 100000000,/ G; {, o% ^9 W
- asset_id: asset_id,5 W$ U' X4 i8 j$ X) _% o6 X
- control_program:control_program- `2 d/ y% F1 C0 X
- }
- const gasAction = {* ~- {& o1 I9 w
- type: 'spend_account',6 M! b/ d3 Z2 s8 E$ T4 G* b
- account_id:account_id,
- asset_alias: 'BTM',
- amount: 50000000% Y2 o8 i7 ^" R2 _4 G/ p
- }
执行合约的参数构造如下:
- const spendAccountUnspentOutput = {
- arguments: [{+ [* g7 p! K/ F
- type: 'data',
- raw_data: {
- // 执行合约输入资产偏移量
- value: '00000000'
- }
- }],6 j% ^/ W+ ]6 l0 V& J& a* W
- output_id: output_id,
- type: 'spend_account_unspent_output'
- }$ |% z. P: F3 M& ~* w2 o- z: R
- // 合约执行提供的资产
- const issueControlAction = {* k. Y8 ^9 C( {$ D9 p1 q
- control_program: control_program,
- amount: 100000000,, `( m, D2 S/ J: e
- asset_id: asset_id,
- type: 'control_program'6 c) |, p9 H7 d! ]
- }1 H- |1 g( O" v
- // 合约执行提供的资产- c% i' t* e+ `
- const issueSpendAction = {/ g( h$ O3 i& J+ v5 v
- account_id: account_id, M+ z, l. s" ~! r# p
- amount: 100000000,
- asset_id: asset_id,
- type: 'spend_account'
- }5 s0 Y% {% g. S/ P
- // 旷工费: M8 _ P0 N& T* I# h8 w+ O8 }
- const gasAction = {1 E! `4 n1 k2 Z/ g
- type: 'spend_account',3 }* N+ h" X# p/ n
- account_id: account_id,( ^( E7 H) e$ \
- asset_alias: 'BTM',. R0 u: Y6 Q; Y g& U* P7 \
- amount: 50000000; ^7 r: ]; r9 P5 E' \; H. \
- }
- // 合约执行获得资产对象
- const controlAction = {
- type: 'control_program',$ N6 M D. f" }
- amount: 100000000,
- asset_id: asset_id,
- control_program: compileData.control_program9 ^/ T8 l6 d% q8 U( l
- }
build 操作其实就是指定输入输出的过程,详情请查看 官方build文档 和 官方api文档. d* {5 [" H& d0 t
备注
调用比原基于okhttp接口javautil 如下:
- public static String sendHttpPost(String bodyStr,String method,String bytomApiserverUrl,String bytomApiserverToken) throws IOException {
- OkHttpClient client = new OkHttpClient();
- MediaType mediaType = MediaType.parse("application/json");
- RequestBody body = RequestBody.create(mediaType, bodyStr);4 R; J. q& ^1 s0 ~6 e
- Request request = new Request.Builder(); M; M3 ?* Y/ D
- .url(bytomApiserverUrl+"/"+method)
- .post(body)) U; D' o) a# S" d" k
- .addHeader("cache-control", "no-cache")
- .addHeader("Connection", "close")
- .build();
- if (bytomApiserverUrl==null || bytomApiserverUrl.contains("127.0.0.1") || bytomApiserverUrl.contains("localhost")){
- }else {
- byte[] encodedAuth = Base64.encodeBase64(bytomApiserverToken.getBytes(Charset.forName("US-ASCII")));
- String authHeader = "Basic " + new String(encodedAuth);
- request = new Request.Builder(): b$ P6 a0 F( [1 K8 g
- .url(bytomApiserverUrl+"/"+method)' F& U- q. y, D9 n" K2 V
- .post(body)
- .addHeader("authorization", authHeader) T& d% [1 Q1 |
- .addHeader("cache-control", "no-cache")
- .addHeader("Connection", "close")
- .build();
- }
- Response response = client.newCall(request).execute();& s% F3 n$ M; O+ `7 X# B
- return response.body().string();
- }
4 p5 F# q# r5 U! n2 V! ?
比原项目仓库:
Github地址:https://github.com/Bytom/bytom
Gitee地址:https://gitee.com/BytomBlockchain/bytom