那如何实现信息上链呢?使用特殊的Retire操作,这个操作可以进行销毁资产的操作,但因为其可以附带信息,所以就可以实现信息上链的功能。 m, Z8 ]6 i3 Y- r
请往下看,也用postman请求演示,然后用golang写了一个接口的demo, 在用golang代码实现之前,我们先要做一些准备工作。2 r- D' F8 a3 ]% u* v
http://test.blockmeta.com/faucet.php! p1 u9 _# k! z
请求build-transaction接口:$ }& j% H0 I% ~) ]5 z$ }0 Y7 b# b* B
% U e$ u3 m' f2 T* j
请求参数:4 v- S$ d y; q3 q
{5 m! s8 z( w: e) ?6 p1 e
"base_transaction": null,, z& `7 W0 i/ [+ y5 ?2 ~0 ?' L
"actions": [{( k* D0 o$ S6 p6 E
"account_id": "0KTCS3R5G0A02",
"amount": 10000000,
"asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",/ v' [5 D# e `& }/ }3 x& U
"type": "spend_account"
}, {
"account_id": "0KTCS3R5G0A02",: K/ H C& h) f s
"amount": 100,
"asset_id": "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd",. m. c) e5 V4 }
"type": "spend_account"
}, {
"account_id": "0KTCS3R5G0A02", ?, l) r( o; ]" \- {
"amount": 100,8 }' G$ x | d9 s# O0 I1 Y
"asset_id": "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd",
"arbitrary": "77656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c",
"type": "retire"/ t! l9 b9 l4 B& S. R5 A5 } ]
}],/ B* k; M9 x8 g Q: S; Q9 K$ {
"ttl": 0,- t4 f7 k% ~( H$ Y$ \
"time_range": 15216258236 U! ^: A& |! [% u3 b# s& {/ s
}$ {8 f- H5 q$ X" p
请求sign-transaction接口:
1 m; o: m3 {+ A, O3 Y
请求参数:: @8 t, K6 S, k0 W. r/ v* f
{
"password": "huangxinglong123",
"transaction": {
"allow_additional_actions": false,3 T5 M& N; K1 P o ~& H6 A
"local": true, f- y% W9 Q3 [+ c5 \3 ?
"raw_transaction": "0701dfd5c8d505020160015e560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0989fe3020001160014adb6632c5b10c6d5b6f97b8d1250f6e409e11c0101000161015f560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd9cc5b191f3190101160014dcfd9b78c24260823e318153665d511d6c4ecb1b010003013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0ebbcde02011600147a9baebd37dba3f14960624ed8e6ca3cc9d5f73800013e608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cdb8c4b191f31901160014f0370fdf7a7bec7b34cc62fd5291071a3dc3d9b0000147608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd6401246a2277656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c00",* t/ S" ^ X% X& U; Z$ {
"signing_instructions": [{1 v' e% p1 T9 s2 V* t# {
"position": 0,7 d, L1 p+ x4 ? d' L, h3 h7 F
"witness_components": [{
"keys": [{* y8 _/ A. A' W3 x- {
"derivation_path": [
"0000002c",
"00000099",+ Z, A2 n" e9 E3 z; C, j+ Y5 Y
"0100000000000000",
"0100000000000000",
"4600000000000000"* \* H' f' \4 x6 ~/ W
],# L8 W& h& r1 R3 r6 B9 [3 Z- ?
"xpub": "1c03161a08a4dbb7df153815a28f733fec1ac7579f954c4834e5ce9f0ad8deb260ecb2066a8623b69aa936f5798f4dcb9572bc476f2c8171953ce054d58a759f"
}],- M& n; d# f0 B' ]4 ~9 @8 E
"quorum": 1,$ U0 T" @8 C+ H9 M
"signatures": null,. S' `8 Z8 Y U# Y, g, a
"type": "raw_tx_signature": j" x# F* t" S+ I/ \) O
}, {0 |; c/ [- l% ]" n
"type": "data",
"value": "4f089176a5bca95ec9227b8a87dfec947c59453805bf46d3f5a18f8032255b5a"
}]3 W' {. J) |9 R; ~+ ~" e
}, {5 ` v( x5 ^0 c% H( N
"position": 1,* ]1 b9 u# C" ^- O: K
"witness_components": [{$ ]) r! _* g1 G2 O' S3 D: h1 l
"keys": [{0 {! t1 J% y$ w0 C6 @+ \5 n
"derivation_path": [6 A' K( j$ a5 w, ~' j
"0000002c",9 j: s8 V" s- m0 r
"00000099",
"0100000000000000",
"0100000000000000",
"4700000000000000"
],
"xpub": "1c03161a08a4dbb7df153815a28f733fec1ac7579f954c4834e5ce9f0ad8deb260ecb2066a8623b69aa936f5798f4dcb9572bc476f2c8171953ce054d58a759f". j" p6 s5 ]* F+ F* p* x8 R: m
}],
"quorum": 1,6 S" t' U0 J; c3 h% Z1 t. O- O
"signatures": null,' u! [- i/ @* M, H1 }5 P: S0 P
"type": "raw_tx_signature"- N( \' b3 X3 e+ I6 Z3 o- S2 o! L
}, {
"type": "data",
"value": "67512f9250f559699e32c72c8af29096b1556af145f6ecc0c306e6acc88bbfaa". y9 V* P; }7 E
}]
}], k; n: }9 {' c. E* S3 i4 H
}
}% z/ n+ ^( o/ V4 }9 K& ^
请求submit-transaction接口:& W. O( n( k( g% e/ Q' w
请求参数:
{
"raw_transaction": "0701dfd5c8d505020160015e560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0989fe3020001160014adb6632c5b10c6d5b6f97b8d1250f6e409e11c01630240c7004022db674ff2961b540d4edab846d550429ae9a92311ba375a4f452331422961fdcde3bf79631755dd12df409e24a849158d4aeab919cab81520fb7d1e02204f089176a5bca95ec9227b8a87dfec947c59453805bf46d3f5a18f8032255b5a0161015f560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd9cc5b191f3190101160014dcfd9b78c24260823e318153665d511d6c4ecb1b6302406b75ef5a9decfa31d4f5ae06e0fb14ca507ba4a03715874d1d831516945121573b9b858e4d7527d209c1f89f74e0aa4c4e38afd098cbadaff31b9107167099012067512f9250f559699e32c72c8af29096b1556af145f6ecc0c306e6acc88bbfaa03013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0ebbcde02011600147a9baebd37dba3f14960624ed8e6ca3cc9d5f73800013e608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cdb8c4b191f31901160014f0370fdf7a7bec7b34cc62fd5291071a3dc3d9b0000147608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd6401246a2277656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c00"
}
响应参数:
{# D: e5 ?- S2 ^! W, s
"status": "success",5 X& A/ I1 m. Y, Q. \
"data": {5 }2 P. w3 h% f/ l
"tx_id": "5ef27b930646d468bbb436d3406972ff201aa63702518f777e31dd6a2147dddc"
}2 u( x% p& t# m' S3 _8 z2 Z
}
用上面返回的tx_id去比原的浏览器中去查看交易详情,就可以查看到我们上传的数据/ C' q8 i/ Z! G: I- o
3 ]& | h8 G3 }& b
参考代码:
package main
import (
"bytes"
"encoding/json"; o$ \+ I2 \8 ^+ r* R6 I
"fmt"# p( {8 S7 j$ X7 n5 B( X
"io/ioutil"
"net/http"
)1 n9 @5 W* j' h/ g d
//build-transaction params
//https://bytom.github.io/mydoc_RPC_call.cn.html#build-transaction D0 ~7 }( t" j1 p7 H
type BytomAccount struct {: y9 q+ f t1 a' e
AccountId string `json:"account_id"`
Amount int `json:"amount"`1 g0 h8 q1 d: Y7 e6 Z5 L
AssetId string `json:"asset_id"`
//Arbitrary string `json:"arbitrary"`+ R6 {- d* H T! h+ ? r
Type string `json:"type"`9 ]- C$ [: u: w( r0 y
}
type BytomAccount1 struct {6 E! d9 j% a7 \0 K3 R! {/ D: ]
AccountId string `json:"account_id"`9 n- O. Y+ I, F! e% o
Amount int `json:"amount"`" c2 W8 a/ K: L' B o/ t' Z6 F
AssetId string `json:"asset_id"`
Arbitrary string `json:"arbitrary"`3 c* C6 l( m: b& \
Type string `json:"type"`3 X0 f+ i3 g* o) Y9 v
}
type BaseTransaction struct{}
type TransactionParams struct {- g- v {9 z/ q, D- u
BaseTransaction *BaseTransaction `json:"base_transaction"`! x* F: r3 K) n% n5 j
Actions []interface{} `json:"actions"`% @: X0 E3 s" `8 q. {/ c
Ttl int `json:"ttl"`
TimeRange int `json:"time_range"`; }5 o$ ~0 i9 j! `5 f2 o
}) L" H% T# {) u9 s8 H [0 I- W. w- d; l
//sign-transaction params& f7 P! e% F) K4 D! y, d
//https://bytom.github.io/mydoc_RPC_call.cn.html#build-transaction- Y* B/ w, a6 N# D# _/ O2 Q; ], v* J: {
type Transaction struct {% k# f# I: x4 J- }2 ~
}( }# g- Y4 s2 k P; N& X) I# T0 i
type SignParams struct {8 t( D( s h8 f! A
Password string `json:"password"`
Transaction Transaction `json:"transaction"`
}8 s; t0 [3 G6 t$ T, i+ W
//submit-transaction
//https://bytom.github.io/mydoc_RPC_call.cn.html#build-transaction
type SubmitParams struct {
RawTransaction string `json:"raw_transaction"`5 t6 G# ~; e* t2 j$ c$ W
}
type SubmitResponse struct {
TxId string `json:"tx_id"`7 Y5 i; t& i1 x. b& V) ]
}
func main() {0 D A* K n% ?, _1 G# p& k
account1, account2, account3 := BytomAccount{}, BytomAccount{}, BytomAccount1{}
account1.AccountId = "0KTCS3R5G0A02"% o4 F4 @$ `5 u
account1.Amount = 10000000
account1.AssetId = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
account1.Type = "spend_account"; `+ ^0 L& K5 ?- R& \$ K- u
account2.AccountId = "0KTCS3R5G0A02"6 |, ^6 [7 l/ U0 u
account2.Amount = 100
account2.AssetId = "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd"9 j' s5 F2 Y o$ ^
account2.Type = "spend_account"
account3.AccountId = "0KTCS3R5G0A02"
account3.Amount = 1002 ?9 ]( v( k/ u/ N2 S- r! G
account3.AssetId = "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd"
account3.Arbitrary = "77656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c"
account3.Type = "retire"
//var array
var actions []interface{}
//append three params
array_actions := append(actions, account1, account2, account3)
transaction_params := &TransactionParams{}
transaction_params.Actions = array_actions" m, u0 d# `: q
transaction_params.Ttl = 0 N* ^ \! d6 j& P( g$ X
transaction_params.TimeRange = 1521625823
//本地测试网节点5 F. Z( m7 |4 Y) L( n4 i
//build-transaction
port := "http://127.0.0.1:9888/build-transaction" L, g( x) v5 {( G* w# _1 F
value, err := SendTransactionRetire(transaction_params, port)' S# A0 r1 |$ I3 ?
if err != nil {, t' I% t7 C; H/ C: L/ U6 e; x
fmt.Println("err:", err)
}
fmt.Println("build-transaction接口返回的参数:", value)
//sign-transaction8 S+ f1 `) q4 A; s3 j
//...........( K/ d! w9 Z) n. I* N) g
//submit-transaction& X Y9 Q" N: S! X: O4 g9 W
//...........
}/ t* w5 Y8 b$ v g# Q) }
//send post request
func SendTransactionRetire(params *TransactionParams, port string) (v interface{}, err error) {; o; X9 I% [5 n0 B& ?/ H
//以本地测试网节点连接
ParamsStr, err := json.Marshal(params)
if err != nil {
return nil, err
}
jsonStr := bytes.NewBuffer(ParamsStr)
fmt.Println(jsonStr)( q6 d# e5 k; p$ r' T/ ^$ @
req, err := http.NewRequest("POST", port, jsonStr)6 c* S$ M0 S$ P4 b
req.Header.Set("Content-Type", "application/json")
req.Header.Add("Accept", "application/json")# l1 B/ R% |: u3 Q4 `
client := &http.Client{}6 u _0 a& F9 D
resp, err := client.Do(req)
if err != nil {0 D# [+ o/ A, I7 u
panic(err)- s0 T. X2 z" `2 A
}7 z: H$ T! p3 Y0 X! W6 n
defer resp.Body.Close()1 y( }: ]& s7 T
var bodyBytes []byte/ H/ ?; G6 J5 v; p
if resp.StatusCode == 200 {
bodyBytes, err = ioutil.ReadAll(resp.Body)
if err != nil {- H# Q, l, U" c# R6 N* j
return nil, err
}/ L# `( e1 J8 P
}% i* R. C0 u8 ?$ r5 X1 O
return string(bodyBytes), nil
}
上面的代码只是build-transaction一个步骤,另外sign-transaction和submit-transaction请求需要自己去组织参数进行请求。请求完submit-transaction 获得返回的交易hash,去区块链浏览器上查看自己的上链信息,区块链浏览器地址:http://52.82.46.157:8082/。- |; U. y- {# F6 G
好了,通过以上的4个步骤,我们就可以借助比原链实现信息上链。如果你有什么疑问或者不明白,请在我们的社区联系我们,https://github.com/Bytom/bytom。