- contract TradeOffer(assetRequested: Asset,, Z, _( m( ]3 i: \1 D$ _/ p' Q9 P' H
- amountRequested: Amount,3 n0 F0 w+ A c2 H6 j+ \
- seller: Program,
- cancelKey: PublicKey) locks offered {
- clause trade() requires payment: amountRequested of assetRequested {+ C/ n1 t! V( i" c* L$ a: d
- lock payment with seller
- unlock offered
- }( x2 I# w3 d, p. t4 l& A0 M
- clause cancel(sellerSig: Signature) {$ [! m1 O$ V8 ]8 o
- verify checkTxSig(cancelKey, sellerSig)
- unlock offered
- }% b& u4 l/ `% L
- }
导读: 初次接触比原只能合约的请点击比原智能合约入门 和 Equity 语言入门 学习,方便更好的理解该文档
锁定合约) E. H6 P$ o; |/ [2 f& ~
第一步:调用create-account-receiver 生成 control_program
以下是相关代码片段:
sendHttpPost("{\"account_id\":\"0IJVD7MNG0A02\"}","create-account-receiver","http://127.0.0.1:9888","");- J, X7 F2 i* {5 h. q0 ?
第二步调用list-pubkeys 获取 pubkey; I( \( Q# ?7 _: l2 F m& D
以下是相关代码片段:8 i* R, }1 i l2 `3 g
sendHttpPost("{\"account_id\":\"0IJVD7MNG0A02\"}","list-pubkeys","http://127.0.0.1:9888","");
第三步: 将1 2步获取的值调用compile接口编译合约获得program 合约程序
; I1 s5 S. M9 `( c* a% T
以下是相关代码片段:( b7 C: S1 J5 L# G
- JSONObject param=new JSONObject();
- JSONArray agrs=new JSONArray();8 I& ^" B( |" z9 o- m& n
- //合约的四个参数值
- JSONObject assetParam=new JSONObject();
- assetParam.put("string","81d097312645696daea84b761d2898d950d8fba0de06c9267d8513b16663dd3a");- f. o3 h( o+ ?8 a
- agrs.put(assetParam);
- JSONObject amountParam=new JSONObject();/ t6 Q% F3 x' C. S; s( U6 a5 \3 c& e
- amountParam.put("integer",200000000l);
- agrs.put(amountParam);+ U4 @ v# L# N( d
- JSONObject programParam=new JSONObject();
- programParam.put("string",control_program);
- agrs.put(programParam);
- JSONObject publicKeyParam=new JSONObject();+ N0 h2 x; \/ r# h: b# _' d5 ~* l
- publicKeyParam.put("string",pubkey);
- agrs.put(publicKeyParam);. N5 U. y5 |1 H3 F4 b- k
- param.put("agrs",agrs);0 {0 e& J/ v- |6 I# f
- 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 } }");9 X3 } s; V" r- O% i
- //调用编译合约
- sendHttpPost(param.toString(),"list-pubkeys","http://127.0.0.1:9888","");
第四步:将program 传入build-transaction接口去build一个交易的到data# X7 c3 |3 H+ _1 R/ S# f. O" Q
6 Z% i8 p* }/ T4 U B! t Z
以下是相关代码片段:6 k; F/ f, n/ d$ i! H. B3 N
- param=new JSONObject();' A0 T& t4 \4 a3 g$ M
- agrs=new JSONArray();( y5 E1 f& |* }) a. b
- JSONObject spendAccount=new JSONObject();+ E: o# U: {6 Z d
- spendAccount.put("account_id","0H757LPD00A02");3 [9 r5 e0 q, |; c% N( D
- spendAccount.put("amount",9909099090000l);, _% n7 J' |& g* k& u" B! h1 W( M
- spendAccount.put("asset_id","161b9767b664df907fa926a31f9e835236e57f3e9ccc5f80c12bd97723322652");
- spendAccount.put("type","spend_account");1 \* G8 {# E+ u- N
- agrs.put(spendAccount); J9 t, j( B' }; t
- JSONObject controlAccount=new JSONObject();+ h. }4 q+ p' c/ X" M* {
- controlAccount.put("control_program",program);$ H v6 y9 G/ D- b# E) z
- controlAccount.put("amount",9909099090000l);
- controlAccount.put("asset_id","161b9767b664df907fa926a31f9e835236e57f3e9ccc5f80c12bd97723322652");; S- \( b" L, q( E$ i
- controlAccount.put("type","control_program");( g8 x' M! c5 u' t9 k9 x3 Y
- agrs.put(controlAccount);: u2 m1 X. ~, e* v" ^" M8 A
- JSONObject spendAccount2=new JSONObject();
- spendAccount2.put("account_id","0H757LPD00A02");
- spendAccount2.put("amount",6000000l);( H2 `* x5 O1 m. C" ~/ r2 R
- spendAccount2.put("asset_id","ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
- spendAccount2.put("type","spend_account");5 w" U2 P9 `# m# a) q" D
- agrs.put(spendAccount2);9 E" H3 d2 l9 j$ k- [% q' v
- param.put("actions",agrs);
- param.put("ttl",0);/ S2 Y! V8 o2 ?; }5 o/ R
- sendHttpPost(param.toString(),"build-transaction","http://127.0.0.1:9888","");
第五步:输入密码调用sign-transaction签名第四步build的data 得到raw_transaction9 }, z8 B! o8 S, k1 d7 Y) m
+ U5 P g3 H4 V& F8 x# o4 \ d) U
以下是相关代码片段:' d% k$ C N+ G; R+ S
param=new JSONObject();
param.put("password","xxx");6 f, w( ^3 j. r$ N
param.put("transaction",data);
sendHttpPost(param.toString(),"sign-transaction","http://127.0.0.1:9888","");
第六步:调用submit-transactions提交交易
0 R- h" u6 g5 m( T
以下是相关代码片段:
param=new JSONObject();; `' i& Y( M% ^! R6 M3 L
param.put("raw_transaction",raw_transaction);6 l9 m+ w1 \. N" z k% ~
sendHttpPost(param.toString(),"submit-transactions","http://127.0.0.1:9888","");1 u0 y/ b: V$ ^8 d
解锁/取消合约
首先需要decode出生成合约时候的参数0 t. Z4 U. u) }
调用list-unspent-outputs 获取生成的合约信息获取program8 p( Z/ A$ y. g/ r, ]7 f
7 {$ W2 O4 ^$ a) ^3 u+ b
以下是相关代码片段:" `2 Z7 r; k1 _1 a! C. {
param=new JSONObject();
param.put("id",outputid); V( G& h# i6 r3 j6 ^/ u
param.put("smart_contract",true);
sendHttpPost(param.toString(),"list-unspent-outputs","http://127.0.0.1:9888","");
调用decode-program 传入获取生成的合约参数信息
以下是相关代码片段:
param=new JSONObject();
param.put("program",program);8 z8 ?" _, }+ ^: E) G
sendHttpPost(param.toString(),"decode-program","http://127.0.0.1:9888","");
需要注意的是decode出来的为值是逆序的(后续会有文章详细介绍)1 ^! z3 @1 E1 K
解锁/取消其实就是把生成合约的步骤中的第三步去掉,替换调用生成合约第四步的参数即可
取消合约的构造参数如下:
0 e k' Y9 k! ^) ^
- spendAccountUnspentOutput = arguments: [{/ q5 H# @! D) Y, k& j& k8 L
- type: 'raw_tx_signature',
- // 生成合约第二步的pubkeylist 详情
- raw_data: {
- derivation_path: pubkeylist.pubkey_infos[0].derivation_path,# \1 \, B9 ]. W0 K8 e
- xpub: pubkeylist.root_xpub+ g u8 o$ n8 f
- }
- }, {+ X/ @! H0 K: ^3 G; t, q
- type: 'data',9 _: ]0 r6 S; T
- raw_data: { A/ a3 ^# T. M1 [8 B
- // 参数偏移量 在一个合约里是固定的 & s. ?0 L8 C! Y- L, f- n7 a
- value: '13000000', b$ l0 ~7 }0 `) G& j
- }
- }],+ \( |8 w9 f3 F9 n1 k- v+ O
- output_id: output_id," g9 N# M- W( {, W i
- type: 'spend_account_unspent_output'! n2 t8 s% D$ Y1 B6 D1 M
- }
- const controlAction = {/ D" F% V* u9 u$ ~1 N3 C
- type: 'control_program',0 [. ~& C) j; e9 y* d! o, ?1 T5 r" v
- amount: 100000000,5 e/ W0 ~& k1 ^* b9 G8 Q' _
- asset_id: asset_id,
- control_program:control_program" @' @% g8 Q4 S7 V' b2 o1 @* w" Q
- }7 |7 |6 @$ V [4 y" S
- const gasAction = {
- type: 'spend_account',; |# L6 Y& T, Z4 Y4 [2 V
- account_id:account_id,
- asset_alias: 'BTM',
- amount: 50000000
- }
执行合约的参数构造如下:% o3 s) w1 @6 M2 K
) Y& t& z. F5 F' j/ D8 j" D
- const spendAccountUnspentOutput = {/ f8 I6 _3 {! p- t# {1 | i4 h
- arguments: [{
- type: 'data',
- raw_data: {4 j" H6 B) e1 c2 j# P3 a6 h
- // 执行合约输入资产偏移量
- value: '00000000'$ d! ], b7 K; @( C. n
- }6 \/ [$ e+ u. ~! W$ b1 K3 X/ `
- }],
- output_id: output_id,7 D0 B9 b: T" v& a' Q
- type: 'spend_account_unspent_output'& ?3 L9 ^) N; C1 J! @% j% r" W
- }
- // 合约执行提供的资产 O( u! G* a8 l5 d% X8 U, t
- const issueControlAction = {
- control_program: control_program,
- amount: 100000000,
- asset_id: asset_id,
- type: 'control_program'
- } G V9 y6 c( [+ f8 i3 D1 T6 P9 C3 ], N
- // 合约执行提供的资产% |2 I/ w: x: a! d( u6 U. _
- const issueSpendAction = {
- account_id: account_id,4 M% e# }% b1 e6 ~4 l% c9 A* b
- amount: 100000000,
- asset_id: asset_id,- o3 j3 O4 V. i7 g5 H
- type: 'spend_account'' k7 ^$ k/ h" F- B; J
- }0 W; z/ V, R7 O+ |- |; q
- // 旷工费
- const gasAction = {* N+ E) W8 {5 j0 }2 B2 V$ X
- type: 'spend_account',5 m' j8 ]- x. c7 \+ |1 ]
- account_id: account_id,4 o. K- o- y! q6 m3 ]- r
- asset_alias: 'BTM',) h8 X7 p* p) A9 M5 _* N
- amount: 50000000
- }3 d) |- _7 `1 V' G
- // 合约执行获得资产对象
- const controlAction = {
- type: 'control_program',! H0 ]/ N2 x. T
- amount: 100000000,
- asset_id: asset_id,( ^7 w& y* I: t! O. `) E' O( B- a
- control_program: compileData.control_program
- }
build 操作其实就是指定输入输出的过程,详情请查看 官方build文档 和 官方api文档
备注) Q# E- a6 }" C8 e5 A
调用比原基于okhttp接口javautil 如下:
- public static String sendHttpPost(String bodyStr,String method,String bytomApiserverUrl,String bytomApiserverToken) throws IOException {
- OkHttpClient client = new OkHttpClient();7 x5 J! ^- C7 _* m3 I, `" ^& U
- MediaType mediaType = MediaType.parse("application/json");
- RequestBody body = RequestBody.create(mediaType, bodyStr); h% {/ C8 P1 ]+ N+ I
- Request request = new Request.Builder()
- .url(bytomApiserverUrl+"/"+method)9 p( S% @1 P" }, E% d, ?; Y
- .post(body)
- .addHeader("cache-control", "no-cache")
- .addHeader("Connection", "close")* f" ^+ m, B; F$ |
- .build();( J& a8 E) J: [$ b
- if (bytomApiserverUrl==null || bytomApiserverUrl.contains("127.0.0.1") || bytomApiserverUrl.contains("localhost")){
- }else {
- byte[] encodedAuth = Base64.encodeBase64(bytomApiserverToken.getBytes(Charset.forName("US-ASCII")));% J' C p' E2 L9 ~; G
- String authHeader = "Basic " + new String(encodedAuth);$ J3 I% |2 D3 _$ E. j2 @
- request = new Request.Builder()
- .url(bytomApiserverUrl+"/"+method)
- .post(body)
- .addHeader("authorization", authHeader)
- .addHeader("cache-control", "no-cache")
- .addHeader("Connection", "close")8 y* M1 X4 g p5 e$ a8 y k
- .build();
- }
- Response response = client.newCall(request).execute();
- return response.body().string();( D5 }5 s/ V, b$ v" n
- }
: b7 J. O, r6 E& s# a
比原项目仓库:; M2 F& l, J5 D3 G8 \* Q, R
Github地址:https://github.com/Bytom/bytom# N' L5 M' [' o5 C5 M: q# ~( n, ]
Gitee地址:https://gitee.com/BytomBlockchain/bytom



