- contract TradeOffer(assetRequested: Asset,
- amountRequested: Amount,& m( s3 F {% K" s) H4 j
- seller: Program,- ~3 ]8 ]2 }3 G# ?, B
- cancelKey: PublicKey) locks offered {$ f. c8 m6 K9 n! S) h9 J
- clause trade() requires payment: amountRequested of assetRequested {
- lock payment with seller
- unlock offered4 [/ b! r) q/ Q& Q
- }
- clause cancel(sellerSig: Signature) {
- verify checkTxSig(cancelKey, sellerSig)
- unlock offered/ \+ w# @6 L! G& A9 g% L
- }
- }
导读: 初次接触比原只能合约的请点击比原智能合约入门 和 Equity 语言入门 学习,方便更好的理解该文档
锁定合约
第一步:调用create-account-receiver 生成 control_program
以下是相关代码片段:+ w, }7 g8 E/ I A
sendHttpPost("{\"account_id\":\"0IJVD7MNG0A02\"}","create-account-receiver","http://127.0.0.1:9888","");* F; S0 o# {7 S; c
第二步调用list-pubkeys 获取 pubkey2 C' F& v5 Q1 k9 i
/ Z5 C* ?; z2 v
以下是相关代码片段:
sendHttpPost("{\"account_id\":\"0IJVD7MNG0A02\"}","list-pubkeys","http://127.0.0.1:9888","");( D4 S/ H4 E' M" d/ e* P8 k
第三步: 将1 2步获取的值调用compile接口编译合约获得program 合约程序
- C' [) x& t3 X, K5 Q
以下是相关代码片段:, ^2 ~- l# ^5 n0 u$ v* {
- JSONObject param=new JSONObject();% t9 g' t$ \0 t" C" D, r! l. z/ c
- JSONArray agrs=new JSONArray();
- //合约的四个参数值* B! s& X2 E7 ?( b3 r
- JSONObject assetParam=new JSONObject();
- assetParam.put("string","81d097312645696daea84b761d2898d950d8fba0de06c9267d8513b16663dd3a");
- agrs.put(assetParam);
- JSONObject amountParam=new JSONObject();0 ~6 W) ?8 M) |% Q b# g: B
- amountParam.put("integer",200000000l);/ N4 Z6 U8 N' d8 A" F& G
- agrs.put(amountParam);, g+ G" X6 V. E3 g
- JSONObject programParam=new JSONObject();
- programParam.put("string",control_program);& C: A3 m7 _, z/ t- j7 D' G ^
- agrs.put(programParam);+ f# C2 J4 j' _0 x/ e' ~
- JSONObject publicKeyParam=new JSONObject();+ o" L6 p2 h W' S ^
- publicKeyParam.put("string",pubkey);
- agrs.put(publicKeyParam);9 d$ p& b- ?0 ]. ?2 V" o
- 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 } }");+ m3 q+ Z) h! {; b2 j0 u* |# X
- //调用编译合约$ k) i+ M6 w% a0 ]: V" O
- sendHttpPost(param.toString(),"list-pubkeys","http://127.0.0.1:9888","");
第四步:将program 传入build-transaction接口去build一个交易的到data% R4 [, F- F* r; s+ k) I0 p# v* r
( ]9 v* v& c" k, s0 T
7 [- o: w/ z# A1 T" v
以下是相关代码片段:& I' ]$ F6 U! N9 t" ^' ?9 P
- param=new JSONObject();/ F+ H% X6 _3 m
- agrs=new JSONArray();
- JSONObject spendAccount=new JSONObject();
- spendAccount.put("account_id","0H757LPD00A02");7 c" l F6 A* y; s% Z# [7 k
- spendAccount.put("amount",9909099090000l);
- spendAccount.put("asset_id","161b9767b664df907fa926a31f9e835236e57f3e9ccc5f80c12bd97723322652");
- spendAccount.put("type","spend_account");
- agrs.put(spendAccount);, f _: j) a1 v# u8 k
- JSONObject controlAccount=new JSONObject();
- controlAccount.put("control_program",program);3 h- m, p/ w. W3 d: F5 J3 S
- controlAccount.put("amount",9909099090000l);6 z: O1 x" f& B, m1 _: j1 [
- controlAccount.put("asset_id","161b9767b664df907fa926a31f9e835236e57f3e9ccc5f80c12bd97723322652");- Z( H4 q1 f# A/ \$ |; r
- controlAccount.put("type","control_program");! ^) V2 k+ D8 w6 g1 c
- agrs.put(controlAccount);& ?9 p/ L+ N: v0 |
- JSONObject spendAccount2=new JSONObject();
- spendAccount2.put("account_id","0H757LPD00A02");) @1 ~, h4 U" m* _
- spendAccount2.put("amount",6000000l);* Y' l4 B; H( o0 H) T
- spendAccount2.put("asset_id","ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");. s* Z8 ^* V( ^
- spendAccount2.put("type","spend_account");" M2 O" b. W% v4 }& m. `4 G) o( p
- 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_transaction0 h" D: N N2 n/ u1 B7 @
3 Z" z( I$ Q( @: G9 m" d2 X
& }8 H3 d& Z" V: D- N
以下是相关代码片段:7 j. {2 |, Z6 F4 y
param=new JSONObject();7 A# l2 B! j$ i% ]- H' r
param.put("password","xxx");2 d& X0 K! D$ K; _
param.put("transaction",data);
sendHttpPost(param.toString(),"sign-transaction","http://127.0.0.1:9888","");
第六步:调用submit-transactions提交交易
以下是相关代码片段:; h- P+ v- F* x' x0 k: A+ O
param=new JSONObject();
param.put("raw_transaction",raw_transaction);4 \6 v& X+ a% N0 V
sendHttpPost(param.toString(),"submit-transactions","http://127.0.0.1:9888","");! f& I& h0 X* Z3 |
解锁/取消合约5 G; s0 v1 O6 o# p& y& l- h
首先需要decode出生成合约时候的参数
调用list-unspent-outputs 获取生成的合约信息获取program
以下是相关代码片段:
param=new JSONObject();
param.put("id",outputid);# f/ r" D$ ~# F9 P N% ~& F: e3 o$ g
param.put("smart_contract",true);
sendHttpPost(param.toString(),"list-unspent-outputs","http://127.0.0.1:9888","");$ B9 j" m% l* S
调用decode-program 传入获取生成的合约参数信息: ~. O0 Y" D; p: y
9 v# o+ F& P0 ?0 N4 q: o
以下是相关代码片段:7 T6 K3 ^$ I8 n
param=new JSONObject();5 n# g1 s3 z1 D2 J4 y2 z: v
param.put("program",program);
sendHttpPost(param.toString(),"decode-program","http://127.0.0.1:9888","");
需要注意的是decode出来的为值是逆序的(后续会有文章详细介绍)
解锁/取消其实就是把生成合约的步骤中的第三步去掉,替换调用生成合约第四步的参数即可
取消合约的构造参数如下:
- spendAccountUnspentOutput = arguments: [{( ^6 D0 D1 i; `
- type: 'raw_tx_signature',
- // 生成合约第二步的pubkeylist 详情
- raw_data: {
- derivation_path: pubkeylist.pubkey_infos[0].derivation_path,* M! ? ?' S8 L9 x6 L5 n7 m
- xpub: pubkeylist.root_xpub, h% |& z: S! S( }) l* u
- }; G9 f9 Q6 \/ ^0 u0 t
- }, {& k6 s) ^/ G- v" \
- type: 'data',! X9 T. k& W+ P
- raw_data: {0 @) |* p5 G+ Q
- // 参数偏移量 在一个合约里是固定的
- value: '13000000'
- }
- }],
- output_id: output_id,
- type: 'spend_account_unspent_output'4 f' c3 Q+ m' T3 O
- }! S# i6 _% f5 z1 @
- const controlAction = {
- type: 'control_program',
- amount: 100000000,
- asset_id: asset_id,
- control_program:control_program* [4 T# r1 Y% V9 Q) `; j
- }
- const gasAction = {
- type: 'spend_account',1 z) d( U, D* R, v* w
- account_id:account_id,* z- L' q, ?! L- K: ~- z/ X/ P
- asset_alias: 'BTM',! j C, v% ?3 a* J
- amount: 500000000 T. a( [- u- |6 _9 n
- }
执行合约的参数构造如下:+ { c6 j* K' ~; |
3 q, R) `, q8 H( H" I8 n. A- U
- const spendAccountUnspentOutput = {
- arguments: [{& e% }/ W7 L% L0 p+ n' z% E
- type: 'data',
- raw_data: {
- // 执行合约输入资产偏移量7 h8 U/ B3 T% ^: W
- value: '00000000'% Y' v4 j$ L l' _' U
- }7 R/ N; ]% K% b* P+ D' F
- }],
- output_id: output_id,
- type: 'spend_account_unspent_output'+ _( ~3 e7 V7 {. X' \. K
- }
- // 合约执行提供的资产+ g K8 j% y/ e3 i/ U
- const issueControlAction = {
- control_program: control_program,
- amount: 100000000,
- asset_id: asset_id,' ?' J: Y* ~& Z% s
- type: 'control_program'' o. z- \0 [5 h' Y) A
- }, Z, Z0 N) J$ D8 L0 B! J- X8 S
- // 合约执行提供的资产
- const issueSpendAction = {2 v7 M# W: J9 N7 ~ R3 _4 ~
- account_id: account_id,, w" p/ V, a! z: H" U8 Q% x+ s) l
- amount: 100000000,
- asset_id: asset_id,* X) X+ ?4 p4 H' c, w
- type: 'spend_account'# E% r+ s+ d. r$ D6 b+ `0 n0 @
- }( }' `6 s) [* Y# r" g# k# i
- // 旷工费. C4 P8 R4 T2 R5 M
- const gasAction = {
- type: 'spend_account',
- account_id: account_id,# A/ w, ?) D, K
- asset_alias: 'BTM',7 R. ^7 X; q8 @8 d, e$ R# A
- amount: 50000000
- }8 K- O' d) B$ q/ p7 t2 A5 Q
- // 合约执行获得资产对象
- const controlAction = {
- type: 'control_program',
- amount: 100000000,
- asset_id: asset_id,
- control_program: compileData.control_program
- }
build 操作其实就是指定输入输出的过程,详情请查看 官方build文档 和 官方api文档
备注2 H! o6 E8 V% {! M% y
调用比原基于okhttp接口javautil 如下:
- public static String sendHttpPost(String bodyStr,String method,String bytomApiserverUrl,String bytomApiserverToken) throws IOException {) S/ L5 [: F5 l# c" q
- OkHttpClient client = new OkHttpClient();
- MediaType mediaType = MediaType.parse("application/json");9 _, B" Y' H2 [
- RequestBody body = RequestBody.create(mediaType, bodyStr);
- Request request = new Request.Builder()) Q* s2 J) I) N. S- X: u
- .url(bytomApiserverUrl+"/"+method)
- .post(body)( A% k# {& ~1 n. R. J: M
- .addHeader("cache-control", "no-cache"). R a" O7 {3 Q# s' x3 I7 K8 _
- .addHeader("Connection", "close")
- .build();
- if (bytomApiserverUrl==null || bytomApiserverUrl.contains("127.0.0.1") || bytomApiserverUrl.contains("localhost")){$ ?+ w: a8 l8 K
- }else {
- byte[] encodedAuth = Base64.encodeBase64(bytomApiserverToken.getBytes(Charset.forName("US-ASCII")));4 a+ H* Q( U2 Y" ^+ l! q
- String authHeader = "Basic " + new String(encodedAuth);
- request = new Request.Builder()$ ^$ d- T. L' k6 d v
- .url(bytomApiserverUrl+"/"+method)
- .post(body)
- .addHeader("authorization", authHeader)
- .addHeader("cache-control", "no-cache")
- .addHeader("Connection", "close")
- .build();
- }5 N7 N c8 z0 G: y# v6 ~+ W* J
- Response response = client.newCall(request).execute(); z% _) m# t P V! @
- return response.body().string();% t5 y$ q0 p) n/ o) n8 w) V
- }
" s0 c8 ~5 w3 [" P/ w* y8 Y* o
比原项目仓库:" z- O. S8 E! Q5 O
Github地址:https://github.com/Bytom/bytom
Gitee地址:https://gitee.com/BytomBlockchain/bytom