- contract TradeOffer(assetRequested: Asset,
- amountRequested: Amount,
- seller: Program,
- cancelKey: PublicKey) locks offered {+ z4 _4 J$ ^/ }
- clause trade() requires payment: amountRequested of assetRequested {
- lock payment with seller
- unlock offered
- }9 z2 W) V. v' n4 H3 t. h4 @
- clause cancel(sellerSig: Signature) {
- verify checkTxSig(cancelKey, sellerSig)
- unlock offered
- }) |, P q( Y5 N: j
- }
导读: 初次接触比原只能合约的请点击比原智能合约入门 和 Equity 语言入门 学习,方便更好的理解该文档
锁定合约6 s* Z* ?5 V! p! f `! V
第一步:调用create-account-receiver 生成 control_program
以下是相关代码片段:
sendHttpPost("{\"account_id\":\"0IJVD7MNG0A02\"}","create-account-receiver","http://127.0.0.1:9888","");0 L+ g; ]# a& n2 Z0 c& \
第二步调用list-pubkeys 获取 pubkey
( ]3 x" N, _/ Y" {- n0 @
以下是相关代码片段:
sendHttpPost("{\"account_id\":\"0IJVD7MNG0A02\"}","list-pubkeys","http://127.0.0.1:9888","");
第三步: 将1 2步获取的值调用compile接口编译合约获得program 合约程序
% q" `# [: S. a2 m3 M
以下是相关代码片段:. R% Z( v! U- ]8 M- f5 T$ d+ O
- JSONObject param=new JSONObject();3 v( j* ^; J) b' K5 R1 V' u; x
- JSONArray agrs=new JSONArray();! s2 I) \4 ~5 Q9 V
- //合约的四个参数值 ?' @; t1 {! K) L- b0 h
- JSONObject assetParam=new JSONObject();
- assetParam.put("string","81d097312645696daea84b761d2898d950d8fba0de06c9267d8513b16663dd3a");' `! E% K) r0 k; i9 v3 B
- agrs.put(assetParam);; t/ q% ~3 T8 d+ S6 v6 }! X
- JSONObject amountParam=new JSONObject();
- amountParam.put("integer",200000000l);
- agrs.put(amountParam);! s% E% R; z# {+ ?4 c( K9 i
- JSONObject programParam=new JSONObject();5 n! [# E% j5 g$ _" p( @ _. R
- programParam.put("string",control_program);
- agrs.put(programParam);5 w) D; p; O, O
- JSONObject publicKeyParam=new JSONObject();
- publicKeyParam.put("string",pubkey);, L5 r+ ~% n7 u' |- r& `
- agrs.put(publicKeyParam);( n. g( o S( p
- 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 } }");0 t0 c; |$ J" w7 e& l
- //调用编译合约9 ^% L% L( P4 Y4 q4 r
- sendHttpPost(param.toString(),"list-pubkeys","http://127.0.0.1:9888","");
第四步:将program 传入build-transaction接口去build一个交易的到data5 n3 i( k6 R1 ~6 D A
- [7 h; V p* P
以下是相关代码片段:4 ?. c t- L% P. ]) R( J
- param=new JSONObject();& R4 \1 ]2 C/ Y$ _+ L- F. w9 X
- agrs=new JSONArray();, M. T- n/ M I& u! U
- JSONObject spendAccount=new JSONObject();; z* v H( y# O+ p1 ?+ _
- spendAccount.put("account_id","0H757LPD00A02");# J% C+ K& G' F9 M1 M z1 l
- spendAccount.put("amount",9909099090000l);
- spendAccount.put("asset_id","161b9767b664df907fa926a31f9e835236e57f3e9ccc5f80c12bd97723322652");) l# g C0 t$ j% D# s* ^* \: B
- spendAccount.put("type","spend_account");
- agrs.put(spendAccount);: t% b2 O) K/ {7 {. ?
- JSONObject controlAccount=new JSONObject();" r+ P9 n/ q! m% m4 C
- controlAccount.put("control_program",program);" n4 ?0 G: Y; ~" Z1 h* A& b
- controlAccount.put("amount",9909099090000l);( ~ _9 _. Q) M" @0 ~
- controlAccount.put("asset_id","161b9767b664df907fa926a31f9e835236e57f3e9ccc5f80c12bd97723322652");9 W, V4 F! v; u2 _: A: t
- controlAccount.put("type","control_program");
- agrs.put(controlAccount);
- JSONObject spendAccount2=new JSONObject();7 t2 c0 n1 Q& m" ?, w) b
- spendAccount2.put("account_id","0H757LPD00A02");
- spendAccount2.put("amount",6000000l);1 A% e" D: f4 X! s- q. V. ~
- spendAccount2.put("asset_id","ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
- spendAccount2.put("type","spend_account");
- agrs.put(spendAccount2);
- param.put("actions",agrs);( l( ]. i& }2 x
- param.put("ttl",0);- y5 }( K2 e9 }2 C. s6 e2 R
- sendHttpPost(param.toString(),"build-transaction","http://127.0.0.1:9888","");
第五步:输入密码调用sign-transaction签名第四步build的data 得到raw_transaction
8 M) {( u* S- w1 F* K3 M- t
以下是相关代码片段:5 q4 L4 j. y$ T1 }; L! T
param=new JSONObject();
param.put("password","xxx");
param.put("transaction",data);
sendHttpPost(param.toString(),"sign-transaction","http://127.0.0.1:9888","");
第六步:调用submit-transactions提交交易
9 b8 y$ e0 \- ]. f9 r2 Z3 L& o
以下是相关代码片段:5 w% [1 K% h ?9 m4 f4 t# ^
param=new JSONObject();2 S- _- l" B8 i( I1 {
param.put("raw_transaction",raw_transaction);
sendHttpPost(param.toString(),"submit-transactions","http://127.0.0.1:9888","");+ i* H$ S, o7 a/ d* l# E
解锁/取消合约
首先需要decode出生成合约时候的参数$ b) W: w6 @0 P& r9 @& H( R6 o
调用list-unspent-outputs 获取生成的合约信息获取program
$ E" i+ A$ k6 N
以下是相关代码片段:: |7 ?0 x2 O3 t' q$ c
param=new JSONObject();
param.put("id",outputid);
param.put("smart_contract",true);
sendHttpPost(param.toString(),"list-unspent-outputs","http://127.0.0.1:9888","");
调用decode-program 传入获取生成的合约参数信息, _- @/ T& M. E) s
以下是相关代码片段: f% n" [! ]3 a" u- C3 X
param=new JSONObject();
param.put("program",program);
sendHttpPost(param.toString(),"decode-program","http://127.0.0.1:9888","");4 T4 b& S. U% ^7 T
需要注意的是decode出来的为值是逆序的(后续会有文章详细介绍)% {4 K0 B2 H8 W& J
解锁/取消其实就是把生成合约的步骤中的第三步去掉,替换调用生成合约第四步的参数即可
取消合约的构造参数如下:
! d7 `; R6 N$ q2 V
- spendAccountUnspentOutput = arguments: [{# B9 q* }7 ^9 u) o- y7 F
- type: 'raw_tx_signature',
- // 生成合约第二步的pubkeylist 详情9 {4 u- ]6 ?# Z- ?: d( {
- raw_data: {- i# Y5 v T% q0 i% B0 p
- derivation_path: pubkeylist.pubkey_infos[0].derivation_path,1 e5 J7 F2 F0 R
- xpub: pubkeylist.root_xpub
- }+ O4 N0 ~# k! l3 `
- }, {
- type: 'data',3 X/ Y6 @7 a+ V0 ~) M
- raw_data: {
- // 参数偏移量 在一个合约里是固定的
- value: '13000000'! H/ o$ N' P& u4 G1 J# T2 R
- }
- }],
- output_id: output_id,
- type: 'spend_account_unspent_output'
- }* E% ~( N6 y- `
- const controlAction = {$ v- U) Z5 a, X0 ?4 r" k* E$ ?
- type: 'control_program',& X3 {# {, y; k1 B2 X
- amount: 100000000,
- asset_id: asset_id,
- control_program:control_program
- }) Q1 j( Z/ Q3 F! c5 l2 w
- const gasAction = {
- type: 'spend_account',
- account_id:account_id,
- asset_alias: 'BTM',
- amount: 50000000# F& K* s2 H4 f- q: B8 \# K: Q
- }
执行合约的参数构造如下:
- const spendAccountUnspentOutput = { z# g V$ A0 L: f( F. C
- arguments: [{- b# k* g2 ^! o% L! x! C" N
- type: 'data',
- raw_data: {% \5 V+ w6 T9 ]) S, D, E
- // 执行合约输入资产偏移量: N; l7 ]; ^. L2 }8 K. ]6 K! I- \
- value: '00000000'
- }
- }],
- output_id: output_id,
- type: 'spend_account_unspent_output'4 h/ t8 V* s6 {
- }
- // 合约执行提供的资产
- const issueControlAction = {& n9 c6 u3 I# D, w! }) D
- control_program: control_program,, \8 q9 h5 e, C# e- n6 `
- amount: 100000000,
- asset_id: asset_id,
- type: 'control_program'5 P8 L' Y0 L3 D+ B5 ]0 p4 m
- }6 v( X N" h$ a, W: N
- // 合约执行提供的资产& J2 y3 a; }$ m `) D6 ^! z- C' M
- const issueSpendAction = {
- account_id: account_id,
- amount: 100000000,
- asset_id: asset_id,6 M1 V9 e" b D; P* o' q
- type: 'spend_account'
- }
- // 旷工费
- const gasAction = {% I( q4 @" i7 P
- type: 'spend_account',
- account_id: account_id,- L2 V8 N; p/ C+ [
- asset_alias: 'BTM',
- amount: 50000000! P& J) [) y/ n% n9 F
- }
- // 合约执行获得资产对象
- const controlAction = {4 W: V6 [3 V& l9 l" p& j6 }
- type: 'control_program',- G" X1 h9 L, M6 s. s, d8 B
- amount: 100000000,# N$ d* T- v' o5 `, _4 a# q
- asset_id: asset_id,. L6 z4 x( a- s3 k/ y
- control_program: compileData.control_program
- }
build 操作其实就是指定输入输出的过程,详情请查看 官方build文档 和 官方api文档; T! G4 p' j- [, C u1 r! L! L
备注7 H9 s" W5 Y$ t% b3 r- {; e
调用比原基于okhttp接口javautil 如下:
- public static String sendHttpPost(String bodyStr,String method,String bytomApiserverUrl,String bytomApiserverToken) throws IOException {
- OkHttpClient client = new OkHttpClient();) m k! k, t# A# {% P4 z) g$ p4 J4 w
- MediaType mediaType = MediaType.parse("application/json");7 S- y( G# o% p1 Y
- RequestBody body = RequestBody.create(mediaType, bodyStr);
- Request request = new Request.Builder()9 C7 J7 Q1 f9 K2 ~# y9 y# z
- .url(bytomApiserverUrl+"/"+method). r+ `6 j7 z4 |) X3 B
- .post(body)
- .addHeader("cache-control", "no-cache")
- .addHeader("Connection", "close")
- .build();4 s9 Y: J9 F8 v7 o
- if (bytomApiserverUrl==null || bytomApiserverUrl.contains("127.0.0.1") || bytomApiserverUrl.contains("localhost")){$ B3 `. m2 A% F2 u2 L D) v
- }else {
- byte[] encodedAuth = Base64.encodeBase64(bytomApiserverToken.getBytes(Charset.forName("US-ASCII")));
- String authHeader = "Basic " + new String(encodedAuth);6 R- J( M! _( Z- `+ K m7 t
- request = new Request.Builder()
- .url(bytomApiserverUrl+"/"+method)
- .post(body)
- .addHeader("authorization", authHeader)5 N( d( |8 I4 ^( x9 w% T
- .addHeader("cache-control", "no-cache")& i% v, m9 L1 e0 m/ h, s
- .addHeader("Connection", "close")
- .build();- U$ n0 o* n" J, _
- }
- Response response = client.newCall(request).execute();
- return response.body().string();9 d% O( ?& @' ]7 W
- }
# ^5 P, T9 U) y' F, ?
! \0 i! v" I7 ^1 ]
比原项目仓库:+ h3 z4 x3 V6 n7 z0 F
Github地址:https://github.com/Bytom/bytom
Gitee地址:https://gitee.com/BytomBlockchain/bytom