- contract TradeOffer(assetRequested: Asset,: ]" i1 n; M& V0 O4 g. u
- amountRequested: Amount,
- seller: Program," \7 G+ |4 H6 O
- cancelKey: PublicKey) locks offered {
- clause trade() requires payment: amountRequested of assetRequested {
- lock payment with seller
- unlock offered% f& b$ w. W* Z i
- }! f! {+ h$ @, R5 I
- clause cancel(sellerSig: Signature) {
- verify checkTxSig(cancelKey, sellerSig). G% T: ~# [% U+ d* A6 g7 ~4 E1 L
- unlock offered
- }- y3 h/ V' G" k6 H
- }
导读: 初次接触比原只能合约的请点击比原智能合约入门 和 Equity 语言入门 学习,方便更好的理解该文档
锁定合约8 V' O; P( S- m
第一步:调用create-account-receiver 生成 control_program5 A8 ?2 h7 {! J7 N: R- u
) A8 O& d7 q& l6 I4 \; I
以下是相关代码片段:4 R) u7 @# H( X: v
sendHttpPost("{\"account_id\":\"0IJVD7MNG0A02\"}","create-account-receiver","http://127.0.0.1:9888","");
第二步调用list-pubkeys 获取 pubkey
6 B# ~- X. M8 v# U
1 D% H4 }" U0 @7 E9 q( A
以下是相关代码片段:
sendHttpPost("{\"account_id\":\"0IJVD7MNG0A02\"}","list-pubkeys","http://127.0.0.1:9888","");
第三步: 将1 2步获取的值调用compile接口编译合约获得program 合约程序. b* Q: P( _5 _' p& T' X) z# J
以下是相关代码片段:
- JSONObject param=new JSONObject();! R+ j* m1 l- E
- JSONArray agrs=new JSONArray();6 S# `2 w9 W3 Y. }( @/ R, m' k
- //合约的四个参数值
- JSONObject assetParam=new JSONObject();1 _: x0 ~# ~$ [# @
- assetParam.put("string","81d097312645696daea84b761d2898d950d8fba0de06c9267d8513b16663dd3a");# V. R: ?! t8 x1 B8 c' o: s
- agrs.put(assetParam);
- JSONObject amountParam=new JSONObject();0 a" y/ ?9 x: U$ R* r
- amountParam.put("integer",200000000l);0 ~2 \" T! q) _" e
- agrs.put(amountParam);
- JSONObject programParam=new JSONObject();! F6 \) D' i. e+ a- w
- programParam.put("string",control_program);+ `' Y+ S* h: |6 A6 s+ w
- agrs.put(programParam);" I" i' L, U0 o) `0 x
- JSONObject publicKeyParam=new JSONObject();
- publicKeyParam.put("string",pubkey);
- agrs.put(publicKeyParam);8 ]' T& P1 e" ^8 j% 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 } }");, Y& k6 d+ e" A
- //调用编译合约% I& U; q! q- N. f8 A9 R9 `
- sendHttpPost(param.toString(),"list-pubkeys","http://127.0.0.1:9888","");
第四步:将program 传入build-transaction接口去build一个交易的到data; [2 y/ i/ \* p/ G! W
# U- p2 E+ p" h
以下是相关代码片段:
- param=new JSONObject();) E! A6 W M7 Y3 t* X
- agrs=new JSONArray();
- JSONObject spendAccount=new JSONObject();
- spendAccount.put("account_id","0H757LPD00A02");
- spendAccount.put("amount",9909099090000l);( k! f: S8 j+ @! ^
- spendAccount.put("asset_id","161b9767b664df907fa926a31f9e835236e57f3e9ccc5f80c12bd97723322652");
- spendAccount.put("type","spend_account");
- agrs.put(spendAccount);. x7 C/ P) X8 R S/ e6 @
- JSONObject controlAccount=new JSONObject();# M4 `% d/ L! F+ U: |
- controlAccount.put("control_program",program);
- controlAccount.put("amount",9909099090000l);
- controlAccount.put("asset_id","161b9767b664df907fa926a31f9e835236e57f3e9ccc5f80c12bd97723322652");% D# N' l9 s/ i
- controlAccount.put("type","control_program");
- agrs.put(controlAccount);
- JSONObject spendAccount2=new JSONObject();- s7 y+ T* y7 D* l! U
- spendAccount2.put("account_id","0H757LPD00A02");
- spendAccount2.put("amount",6000000l);; S+ o m* H4 G# m9 M( u
- spendAccount2.put("asset_id","ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
- spendAccount2.put("type","spend_account");
- agrs.put(spendAccount2);
- param.put("actions",agrs);
- param.put("ttl",0);3 h4 m/ r5 W) }/ u7 K
- sendHttpPost(param.toString(),"build-transaction","http://127.0.0.1:9888","");
第五步:输入密码调用sign-transaction签名第四步build的data 得到raw_transaction4 L4 e: G. T3 r# o1 g
) C Y! _5 N; G/ ]9 p/ I
以下是相关代码片段:
param=new JSONObject();/ w% W9 }! u6 m7 H. T0 u8 _+ O' Z5 r
param.put("password","xxx");7 P4 P/ S; a* A* r% O
param.put("transaction",data);
sendHttpPost(param.toString(),"sign-transaction","http://127.0.0.1:9888",""); w$ t( b2 J3 m# l7 E; v5 X! g8 I
第六步:调用submit-transactions提交交易
3 Y2 h+ r/ n6 ?+ l3 m( C% n
以下是相关代码片段:
param=new JSONObject();
param.put("raw_transaction",raw_transaction);
sendHttpPost(param.toString(),"submit-transactions","http://127.0.0.1:9888","");
解锁/取消合约
首先需要decode出生成合约时候的参数
调用list-unspent-outputs 获取生成的合约信息获取program
以下是相关代码片段:
param=new JSONObject();6 Y0 _0 j7 `7 f4 q1 @
param.put("id",outputid);
param.put("smart_contract",true);
sendHttpPost(param.toString(),"list-unspent-outputs","http://127.0.0.1:9888","");3 C5 e6 s- n, E- A3 r
调用decode-program 传入获取生成的合约参数信息. H5 x1 D* H$ w* w: g7 q' F/ T4 q" o
6 m; k1 Y. }: ?, u' b+ I" K7 J
以下是相关代码片段:9 U9 i) P8 o- V/ ?& Y
param=new JSONObject();
param.put("program",program);2 x! b+ p5 y. m/ ~: a
sendHttpPost(param.toString(),"decode-program","http://127.0.0.1:9888","");7 A1 H" ~. M) t. K! b4 _
需要注意的是decode出来的为值是逆序的(后续会有文章详细介绍)
解锁/取消其实就是把生成合约的步骤中的第三步去掉,替换调用生成合约第四步的参数即可
取消合约的构造参数如下:
4 a; q2 V z2 ?4 M. X4 ?
- spendAccountUnspentOutput = arguments: [{2 f# f3 m7 D! U* P" `* W) N
- type: 'raw_tx_signature',
- // 生成合约第二步的pubkeylist 详情0 `4 w2 S! j2 F8 G! q0 ?; D6 R
- raw_data: {
- derivation_path: pubkeylist.pubkey_infos[0].derivation_path,
- xpub: pubkeylist.root_xpub% g" @( _! F0 y+ P
- }
- }, {# L: r+ J! h% R) d& K
- type: 'data',
- raw_data: {7 o! ?2 J0 ^( y8 {1 Y
- // 参数偏移量 在一个合约里是固定的
- value: '13000000'
- }
- }],* Y1 r) f" F) z
- output_id: output_id,
- type: 'spend_account_unspent_output'
- }
- const controlAction = {- \/ O, k3 M+ `, I
- type: 'control_program',8 i6 Q! K6 c7 G) F+ B! M
- amount: 100000000,8 |$ ]; R5 T* y0 u" ]& J! D. r
- asset_id: asset_id,
- control_program:control_program
- }
- const gasAction = {6 l! j0 K& }) [
- type: 'spend_account',
- account_id:account_id,
- asset_alias: 'BTM',
- amount: 50000000
- }
执行合约的参数构造如下:; P* D. V) B* `: Q& I8 P) l
# o+ p) m3 g0 @
- const spendAccountUnspentOutput = {0 z0 s' p! R+ h e3 }5 h: J5 o
- arguments: [{0 o: E) X" o- ?. C# t- T+ Q2 F" c0 U
- type: 'data',
- raw_data: {9 S5 a" X/ z1 S) ?
- // 执行合约输入资产偏移量
- value: '00000000'
- }6 ?6 ^" R( ?# A% [
- }],# Z1 M5 Y2 m" P5 f1 v
- output_id: output_id,
- type: 'spend_account_unspent_output'" q1 M* e; u$ {$ P2 m
- }
- // 合约执行提供的资产- d$ [; L5 p. T7 E
- const issueControlAction = {
- control_program: control_program,9 F! V7 p. t! s- v |8 _
- amount: 100000000,
- asset_id: asset_id,
- type: 'control_program'" B5 [$ }) @% A0 ?* { h# l2 j- Y
- }, g3 y4 G1 |0 i* H: ^8 e2 z4 l
- // 合约执行提供的资产
- const issueSpendAction = {
- account_id: account_id,. n9 ]& I. q0 H# {
- amount: 100000000, O0 t4 }* T; ~" s' k6 o3 R9 @
- asset_id: asset_id,% q1 @' v! C: G- ^" P
- type: 'spend_account'4 N/ ?9 ]3 D+ k. x% b
- }
- // 旷工费# g: V2 k9 B$ d% r% I5 m" p
- const gasAction = {
- type: 'spend_account',
- account_id: account_id,+ o' d+ |+ Z8 t# G( l9 e
- asset_alias: 'BTM',
- amount: 50000000
- }& H+ {& \9 ~4 c3 c# W
- // 合约执行获得资产对象
- const controlAction = {! A3 l, I6 ^4 ]; |, o: M# S
- type: 'control_program',4 q! W5 T" K. E
- amount: 100000000,+ I% |( {6 @8 J" w9 `- a
- asset_id: asset_id,
- control_program: compileData.control_program! z% h" A0 R% t0 s# ^1 o6 x# c2 O
- }
build 操作其实就是指定输入输出的过程,详情请查看 官方build文档 和 官方api文档
备注
调用比原基于okhttp接口javautil 如下:3 m+ ]/ U. M( L9 M z# U0 q* \
- public static String sendHttpPost(String bodyStr,String method,String bytomApiserverUrl,String bytomApiserverToken) throws IOException {
- OkHttpClient client = new OkHttpClient();5 m+ t5 p% k! _+ a% M. }* H
- MediaType mediaType = MediaType.parse("application/json");, \2 y# Z/ T1 B# a n5 O3 ~+ Y
- RequestBody body = RequestBody.create(mediaType, bodyStr);9 E V5 A: Q7 b$ j
- Request request = new Request.Builder()
- .url(bytomApiserverUrl+"/"+method)9 k6 Y! l8 `% E1 O, Z6 D0 ]
- .post(body)
- .addHeader("cache-control", "no-cache") u4 F4 W6 q4 c. ]: p
- .addHeader("Connection", "close")
- .build();( z0 p3 u2 R* s, c7 Z
- if (bytomApiserverUrl==null || bytomApiserverUrl.contains("127.0.0.1") || bytomApiserverUrl.contains("localhost")){ F5 h% Q- o4 Q
- }else {) U$ Z) ?1 X, C4 b" P
- byte[] encodedAuth = Base64.encodeBase64(bytomApiserverToken.getBytes(Charset.forName("US-ASCII")));0 P4 c2 t, M# r# X* K: l+ {5 l; I' K
- String authHeader = "Basic " + new String(encodedAuth);
- request = new Request.Builder()
- .url(bytomApiserverUrl+"/"+method), A- Q( e) [! I% r9 O) e' m
- .post(body)% {# ^7 z( M0 S5 [
- .addHeader("authorization", authHeader)* Y) |& }3 c+ b7 p. h& W& u1 l
- .addHeader("cache-control", "no-cache")
- .addHeader("Connection", "close")
- .build();
- }! M" b2 H9 E" g
- Response response = client.newCall(request).execute();: ~7 k" y# m, Z, o& U
- return response.body().string();/ b9 f! S* y+ b$ P' ^ S U: U# m
- }
比原项目仓库:
Github地址:https://github.com/Bytom/bytom
Gitee地址:https://gitee.com/BytomBlockchain/bytom