那如何实现信息上链呢?使用特殊的Retire操作,这个操作可以进行销毁资产的操作,但因为其可以附带信息,所以就可以实现信息上链的功能。+ [. j, f. m, m- Y# x1 o8 Z' q
请往下看,也用postman请求演示,然后用golang写了一个接口的demo, 在用golang代码实现之前,我们先要做一些准备工作。
http://test.blockmeta.com/faucet.php4 C8 m* z+ ?. ?, F. s
请求build-transaction接口:7 U4 ?9 ]4 s B. L
请求参数:
{& [" d4 w+ o' G5 f! E
"base_transaction": null,
"actions": [{
"account_id": "0KTCS3R5G0A02",# l3 Q4 c" x' P; K# i0 C
"amount": 10000000,
"asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"type": "spend_account"% x$ N! B7 f5 |" M- m+ ?- A- V
}, {
"account_id": "0KTCS3R5G0A02",( L9 L5 \/ g. V' z8 p( m& D$ v
"amount": 100,+ i, N# D2 V# D4 O, l
"asset_id": "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd",
"type": "spend_account"
}, {$ z/ W6 R9 j6 x) Z
"account_id": "0KTCS3R5G0A02",- m" b7 x9 w( n: H) L& @/ g; @) W) z3 D
"amount": 100,% R2 \# ^$ a2 X. N, ]7 ?" Y
"asset_id": "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd",- Z! v: K: F7 s; l: ^& T
"arbitrary": "77656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c",/ N4 ^! l& D! S- M6 X
"type": "retire"/ C7 a! N6 g: ?. D7 r
}],3 G7 @" K% V+ d4 A$ `
"ttl": 0,0 B+ Q# ]3 W% q ]& D- g! g4 k
"time_range": 1521625823; C2 Q# T, p4 o
}7 I! j8 K# s0 w) F) }! o4 v! A
请求sign-transaction接口:
: R4 I9 g3 Y3 U6 z' w3 o5 U' {7 K
请求参数:
{
"password": "huangxinglong123",
"transaction": {" m6 ~# |' \* l
"allow_additional_actions": false,# t! a/ Z/ I3 {: v2 F5 J( O
"local": true,1 N* ]- i8 w) ]/ |
"raw_transaction": "0701dfd5c8d505020160015e560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0989fe3020001160014adb6632c5b10c6d5b6f97b8d1250f6e409e11c0101000161015f560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd9cc5b191f3190101160014dcfd9b78c24260823e318153665d511d6c4ecb1b010003013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0ebbcde02011600147a9baebd37dba3f14960624ed8e6ca3cc9d5f73800013e608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cdb8c4b191f31901160014f0370fdf7a7bec7b34cc62fd5291071a3dc3d9b0000147608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd6401246a2277656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c00",
"signing_instructions": [{
"position": 0,
"witness_components": [{# x. e& O3 b- b
"keys": [{
"derivation_path": [# H# I) n* w3 x! } M7 F
"0000002c",
"00000099",4 i5 u/ e( x" u% x
"0100000000000000",
"0100000000000000",
"4600000000000000"
],
"xpub": "1c03161a08a4dbb7df153815a28f733fec1ac7579f954c4834e5ce9f0ad8deb260ecb2066a8623b69aa936f5798f4dcb9572bc476f2c8171953ce054d58a759f") o- u! W! f; k" A) Q% f: V( ]
}],2 c. Q: @ K# y. \- X" w- E7 V" M
"quorum": 1,% H* }4 b i! V6 ?* T3 Z, _
"signatures": null,/ r: Y8 ?9 p$ l2 c4 z. L
"type": "raw_tx_signature"' O! ?2 I }* L
}, {
"type": "data",
"value": "4f089176a5bca95ec9227b8a87dfec947c59453805bf46d3f5a18f8032255b5a"! F1 k, r6 P; D" y7 Q8 ?& u
}]
}, {% K( Z- C4 e3 y- d4 o
"position": 1,8 g" h1 c k* h: b# a4 f' }" s
"witness_components": [{* b9 _! j) ?0 z
"keys": [{
"derivation_path": [
"0000002c",7 j; X% c, [( p* h4 |
"00000099",
"0100000000000000",
"0100000000000000",- C* u8 p4 j0 H5 d1 s/ E
"4700000000000000"& h- T) h" r! @# L# x5 |# Y
],
"xpub": "1c03161a08a4dbb7df153815a28f733fec1ac7579f954c4834e5ce9f0ad8deb260ecb2066a8623b69aa936f5798f4dcb9572bc476f2c8171953ce054d58a759f"2 h" w+ k B) \% }( C# u
}],
"quorum": 1,
"signatures": null,
"type": "raw_tx_signature"# F: {5 e/ L$ w, y
}, {4 Q" P) C) G( O Y5 y
"type": "data",
"value": "67512f9250f559699e32c72c8af29096b1556af145f6ecc0c306e6acc88bbfaa"
}]0 {! |1 J& B' F+ f i0 k) D- i
}]
}7 d6 H3 e D: q4 d$ t6 j5 u/ {
}
请求submit-transaction接口:. f$ e) ]& T5 j& [- {
6 ?1 @3 `) P7 H0 J9 N4 u
请求参数:
{+ y: L2 Z; L; D6 D% E6 g
"raw_transaction": "0701dfd5c8d505020160015e560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0989fe3020001160014adb6632c5b10c6d5b6f97b8d1250f6e409e11c01630240c7004022db674ff2961b540d4edab846d550429ae9a92311ba375a4f452331422961fdcde3bf79631755dd12df409e24a849158d4aeab919cab81520fb7d1e02204f089176a5bca95ec9227b8a87dfec947c59453805bf46d3f5a18f8032255b5a0161015f560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd9cc5b191f3190101160014dcfd9b78c24260823e318153665d511d6c4ecb1b6302406b75ef5a9decfa31d4f5ae06e0fb14ca507ba4a03715874d1d831516945121573b9b858e4d7527d209c1f89f74e0aa4c4e38afd098cbadaff31b9107167099012067512f9250f559699e32c72c8af29096b1556af145f6ecc0c306e6acc88bbfaa03013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0ebbcde02011600147a9baebd37dba3f14960624ed8e6ca3cc9d5f73800013e608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cdb8c4b191f31901160014f0370fdf7a7bec7b34cc62fd5291071a3dc3d9b0000147608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd6401246a2277656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c00"2 c. @8 r: x9 |( Y9 W
}. e7 Z7 Y$ [) a) \/ S
响应参数:
{
"status": "success",
"data": {
"tx_id": "5ef27b930646d468bbb436d3406972ff201aa63702518f777e31dd6a2147dddc"
}7 r7 w# s( d. G' h
}
: i3 m$ J9 u% E2 F. _* p
用上面返回的tx_id去比原的浏览器中去查看交易详情,就可以查看到我们上传的数据
参考代码:6 |7 z" j) n( D) p
package main
import (
"bytes"5 U; ]. l( Q. k1 f
"encoding/json"
"fmt": D( |2 S* D" O
"io/ioutil", V$ P" P) {4 t ?
"net/http"2 v+ S, E: p( F; d/ Y
)0 k. ~+ z5 U. _) ~
//build-transaction params. x# h( M% N! P& A
//https://bytom.github.io/mydoc_RPC_call.cn.html#build-transaction! @1 b! ]' u5 V' I
type BytomAccount struct {
AccountId string `json:"account_id"`4 Z+ A/ \+ W3 p7 t! b% k
Amount int `json:"amount"`
AssetId string `json:"asset_id"`
//Arbitrary string `json:"arbitrary"`- O9 f; B! G1 {* W$ Y
Type string `json:"type"`
}, j- d+ I; [- s8 j3 l6 B4 {
type BytomAccount1 struct {: G5 @+ X( y& j& n4 P
AccountId string `json:"account_id"`7 Y0 i3 K' |1 \# [- f7 E
Amount int `json:"amount"`
AssetId string `json:"asset_id"`
Arbitrary string `json:"arbitrary"`
Type string `json:"type"`
}
type BaseTransaction struct{}
type TransactionParams struct {2 F4 e i0 q% n3 E, {
BaseTransaction *BaseTransaction `json:"base_transaction"`
Actions []interface{} `json:"actions"`8 L" {" j$ S" g: o
Ttl int `json:"ttl"`
TimeRange int `json:"time_range"`* `2 v. W3 M" Y1 ?) g
}
//sign-transaction params
//https://bytom.github.io/mydoc_RPC_call.cn.html#build-transaction( R! V$ c3 t2 t( I8 h* t) n$ @
type Transaction struct {- |" i) K8 U5 i! k. X
}; l0 t% y. x- R8 H2 l" p0 ~8 W8 A, W T
type SignParams struct {- p# `7 F7 E/ i$ z/ S7 Y
Password string `json:"password"`
Transaction Transaction `json:"transaction"`& `* f3 j9 B( C# ^
}( G V3 ]5 `; M: _+ P
//submit-transaction/ _1 B1 M; w8 H9 ~; B8 Q, l% d" W# l
//https://bytom.github.io/mydoc_RPC_call.cn.html#build-transaction. B7 f+ ?; Q1 G V; O) t7 x
type SubmitParams struct {. {! m7 l/ e3 c; q7 `+ a z' ^- i
RawTransaction string `json:"raw_transaction"`! a0 Y" m# ?; O* G
}
type SubmitResponse struct {
TxId string `json:"tx_id"`
}
func main() {7 N) x0 ]( v% A8 M& S
account1, account2, account3 := BytomAccount{}, BytomAccount{}, BytomAccount1{}
account1.AccountId = "0KTCS3R5G0A02"" D, J1 C" Y. i T
account1.Amount = 10000000
account1.AssetId = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
account1.Type = "spend_account"+ U' ^! y* k) i F
account2.AccountId = "0KTCS3R5G0A02"
account2.Amount = 1008 C# y$ J4 }, _: j6 L6 n4 H& t
account2.AssetId = "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd"5 f$ J' f6 K$ k( \2 h
account2.Type = "spend_account"" L; Z, k& Z# w( T1 e8 B
account3.AccountId = "0KTCS3R5G0A02"' q8 V, r+ m. S$ k- B
account3.Amount = 1009 w9 G: B5 z# V5 W4 l2 r+ Y0 p
account3.AssetId = "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd"
account3.Arbitrary = "77656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c"3 M& s- @$ ]# x% h
account3.Type = "retire"
//var array
var actions []interface{}
//append three params, e5 X- y# \: \. N& J8 l
array_actions := append(actions, account1, account2, account3)7 n/ h. f- B; J2 F
transaction_params := &TransactionParams{}! F5 x# c/ O: k: ?" x" J
transaction_params.Actions = array_actions7 e" f9 t4 g9 T
transaction_params.Ttl = 0
transaction_params.TimeRange = 1521625823
//本地测试网节点
//build-transaction
port := "http://127.0.0.1:9888/build-transaction"
value, err := SendTransactionRetire(transaction_params, port)4 U; V; n& b* X- h! P: ?6 R) h" m8 Z
if err != nil {7 f# T& ~5 o* ~7 @
fmt.Println("err:", err)! Y5 \' M c8 S9 d
}
fmt.Println("build-transaction接口返回的参数:", value)2 J" [- P4 l, X) N
//sign-transaction# L1 b. c6 S# P5 }
//...........
//submit-transaction$ r+ _' i" e- u8 T2 n4 g
//...........
}: Q% e+ y# t) z6 h, V
//send post request0 l9 x I$ D( b i, V# c/ h
func SendTransactionRetire(params *TransactionParams, port string) (v interface{}, err error) {
//以本地测试网节点连接2 X4 k+ k+ F( E8 h
ParamsStr, err := json.Marshal(params)
if err != nil {4 m7 s. F9 A3 S
return nil, err
}
jsonStr := bytes.NewBuffer(ParamsStr)' W* y, `8 Q) d
fmt.Println(jsonStr)
req, err := http.NewRequest("POST", port, jsonStr)+ f( X9 X7 q2 {& S0 R5 \' l
req.Header.Set("Content-Type", "application/json")
req.Header.Add("Accept", "application/json")6 {0 g+ H/ k+ c- ]# F
client := &http.Client{}& H- P# R4 I' } V% Z
resp, err := client.Do(req)
if err != nil {/ B# X1 Y# V1 o4 G6 {5 G
panic(err)& B. [# z7 @, r& }3 k1 n
}, p# l! C' T5 V; f
defer resp.Body.Close()
var bodyBytes []byte, t; ^8 G: D& j. _ U! O- j
if resp.StatusCode == 200 {1 s, _+ L% l- b7 U. Q
bodyBytes, err = ioutil.ReadAll(resp.Body)) c; Y5 f9 g7 d
if err != nil {6 g6 {# S4 x; P5 ~- }& }6 Q* U
return nil, err2 S5 k4 Z0 d2 _$ C
}& \4 D! v; M2 k7 g
}
return string(bodyBytes), nil4 S+ n) B) U) Y+ O
}
上面的代码只是build-transaction一个步骤,另外sign-transaction和submit-transaction请求需要自己去组织参数进行请求。请求完submit-transaction 获得返回的交易hash,去区块链浏览器上查看自己的上链信息,区块链浏览器地址:http://52.82.46.157:8082/。) P' D5 g: `/ u0 k3 F
好了,通过以上的4个步骤,我们就可以借助比原链实现信息上链。如果你有什么疑问或者不明白,请在我们的社区联系我们,https://github.com/Bytom/bytom。



