Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用比原链(Bytom)实现信息上链

wzls3146
115 0 0
很多了解比原链的都知道,比原链是专注信息和数字资产在链上交互和流转的公链项目,信息上链不是比原链核心能力,所以并没有在钱包端做一个功能入口,但是比原链提供了相关的接口可以将一些信息写到链上去。
4 x' d# C0 C5 r, J  u6 x8 N那如何实现信息上链呢?使用特殊的Retire操作,这个操作可以进行销毁资产的操作,但因为其可以附带信息,所以就可以实现信息上链的功能。. |( ^* I. U9 z4 T
请往下看,也用postman请求演示,然后用golang写了一个接口的demo, 在用golang代码实现之前,我们先要做一些准备工作。
! X8 _' h! ~/ Q3 O9 s. p/ v& |. i
  • 首先确保自己在本地已经搭建好了比原的节点,如果你还没有搭建好节点,请参考开发文档:https://docs.bytom.io/mydoc_build_environment.cn.html
  • 确保自己账户是有足够BTM测试币,如果没有可以去比原链水龙头领取BTM测试币,领取地址:
    * R2 c9 Z9 P9 V; t7 M

    8 J, m1 F7 O0 N' Z$ Y% w; Ghttp://test.blockmeta.com/faucet.php) x: T, `1 I) S! q! W) ?$ g! R
  • 发行自己的资产,参考:https://bbs.8btc.com/forum.php?mod=viewthread&tid=242940&extra=
  • 信息上链的本质就是其实就是创建并发送一笔交易,我们都知道通过api发起交易主要有三个步骤,先 build → sign → submit,分别对应的api是 build-transaction、sign-transaction、submit-transaction。用postman请求过程如下:2 Z, a; N1 K4 w  u0 R6 f+ P; ?
    ( y, b! C: n3 x; v
    请求build-transaction接口:
    3 O4 m4 }8 d4 I. Y# x& L' z- S( ^9 ~
    请求参数:
    1 i$ `$ a3 A$ B3 ?3 j{
    1 b9 r# V2 U, E1 L7 h9 z/ b5 e"base_transaction": null,6 M2 m) _7 I& [: F# `
    "actions": [{) F/ c' f: ]2 \) K/ b4 x
            "account_id": "0KTCS3R5G0A02",
    ' A7 G8 Y( W. \% A+ ~        "amount": 10000000,
    : ~1 U" y  S+ a        "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
    4 V3 v4 v6 p. K8 X. q        "type": "spend_account"
    3 z4 Y0 D" T! s- B3 }}, {
    / i2 P2 {- n1 V; S        "account_id": "0KTCS3R5G0A02",
      P% P$ |, q+ ^" ~8 h9 \! l        "amount": 100,8 r: t- E# m! q! o) k1 G
            "asset_id": "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd",
    5 E/ T3 B6 [+ x: O' L        "type": "spend_account"
    " c( O* k( B9 A* ]* }$ q2 g}, {
    " j2 v& E& `/ A" R$ `2 m3 G        "account_id": "0KTCS3R5G0A02",
    2 x0 ]7 D7 D: n- F* m6 V2 w1 D        "amount": 100,
    ) q1 @6 b- K6 Y+ ^        "asset_id": "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd",
    / H( F) G- a- W: d% e& C! h0 t0 L        "arbitrary": "77656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c",# u& S1 Q( U" c% X
            "type": "retire"( b, q. }7 c3 M- P# @, w
    }],
    6 h" s$ E8 K$ ^, g5 W& Q"ttl": 0,
    & C( A, g. @4 A! E! W"time_range": 15216258233 L: v& K9 |$ Q8 h! {4 z( w
    }
    " ]8 D7 b' `! H: T0 x/ I5 X请求sign-transaction接口:- O4 _7 p# Y4 C6 d6 w. R! ?* l
    * T8 t9 R  z" \! N! W
    请求参数:+ s4 s( y! A& m8 e
    {
    5 v) f5 i7 Z# u"password": "huangxinglong123",
    * V+ J% Y9 o3 b' O4 `* P: G"transaction": {* E- N: }3 M( z& }5 u
            "allow_additional_actions": false,7 R* g0 l4 V; ^$ H/ e; n) G
            "local": true,
    3 X2 d% R) c; W2 q* O6 ]        "raw_transaction": "0701dfd5c8d505020160015e560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0989fe3020001160014adb6632c5b10c6d5b6f97b8d1250f6e409e11c0101000161015f560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd9cc5b191f3190101160014dcfd9b78c24260823e318153665d511d6c4ecb1b010003013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0ebbcde02011600147a9baebd37dba3f14960624ed8e6ca3cc9d5f73800013e608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cdb8c4b191f31901160014f0370fdf7a7bec7b34cc62fd5291071a3dc3d9b0000147608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd6401246a2277656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c00",
    6 E5 c5 j* ~4 r! |" L        "signing_instructions": [{! T3 W4 \$ D) f( f, q/ M0 @
                    "position": 0,
    + C; o" p. ?( r4 O1 \( X) f+ {                "witness_components": [{' o4 f* d8 `0 X6 j% j! L
                            "keys": [{
      W, L% k4 U5 c" l                                "derivation_path": [) B1 l5 A1 R/ w0 l1 _: Z
                                            "0000002c"," N0 V: e" Q- V& `
                                            "00000099",
    4 J2 M/ o3 B/ E+ _# B                                        "0100000000000000",% n" Z/ i% j7 L" [: ?
                                            "0100000000000000",9 \- t( `1 J+ f8 ~
                                            "4600000000000000"
    0 B7 b9 ]0 h! e# w                                ],4 X" v, ^; I8 H" V( Z
                                    "xpub": "1c03161a08a4dbb7df153815a28f733fec1ac7579f954c4834e5ce9f0ad8deb260ecb2066a8623b69aa936f5798f4dcb9572bc476f2c8171953ce054d58a759f") s' ?" @7 K* @
                            }],
    ( v" @* f7 q2 i/ Z# U9 @: \                        "quorum": 1,) t! H& ]% j0 N2 L7 U; M
                            "signatures": null,% w' n) n& n; n- U
                            "type": "raw_tx_signature"
    2 k2 f0 T3 F% C1 Z. t- \% t  U, a                }, {
    : V# C# i5 _# ?5 ~( u                        "type": "data",! J, t6 V  x3 Q0 `6 A2 W; Y
                            "value": "4f089176a5bca95ec9227b8a87dfec947c59453805bf46d3f5a18f8032255b5a"
    ) Y! m5 N( ^6 e8 l  S# l                }]& z. s( v7 l) J, J" x4 J
            }, {
    * t! P+ v( Y9 N- |                "position": 1,
    , S. ^! K$ H4 T7 t# H                "witness_components": [{
    1 x5 ^# Z, @6 o                        "keys": [{
    + E* {+ S4 c4 f( x' K6 x                                "derivation_path": [
    + K9 l0 Z5 A% @. W* q7 H* f                                        "0000002c",
    8 c' I, g9 a( [/ F, N& c: }3 [  i/ M                                        "00000099",
      R$ d" S4 }( E" S6 K; A                                        "0100000000000000",
    7 Q, |' Y7 N( U6 X                                        "0100000000000000",
    $ G& S  I& W5 n' F$ U  Z& a                                        "4700000000000000"
    % x% d1 J0 D8 a4 M- i4 O" F                                ],* f4 z4 F: d! T: X
                                    "xpub": "1c03161a08a4dbb7df153815a28f733fec1ac7579f954c4834e5ce9f0ad8deb260ecb2066a8623b69aa936f5798f4dcb9572bc476f2c8171953ce054d58a759f"
    ) i" q7 K9 P% @8 \                        }],* l" h5 L' Q- x0 h6 f5 M% u
                            "quorum": 1,& d, y5 |3 E& b& Q. ~! u6 ?
                            "signatures": null,1 d8 i# e' w; f  a3 Y
                            "type": "raw_tx_signature"
    4 o& K  d! A( x) p3 c3 _9 }* s" H                }, {
    ! M# n( K/ f& o                        "type": "data",
    & H: F4 T! |2 U" y2 C1 y' v, y                        "value": "67512f9250f559699e32c72c8af29096b1556af145f6ecc0c306e6acc88bbfaa"
    # r3 w  V9 |; p                }]: E3 H3 s8 ~8 v% _3 N
            }]
    ( N6 H1 Q  T. r2 G}/ C" G3 s( X0 ^4 h
    }
    4 z/ d4 M1 G; w, I4 X请求submit-transaction接口:
    8 w# u& y  n) x+ b) M6 l4 {5 ]/ x! v8 `* o: g- A
    请求参数:
    8 d+ f9 i, Z* e8 l( `8 _8 Y {0 @6 e& u7 N! }- Q
    "raw_transaction": "0701dfd5c8d505020160015e560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0989fe3020001160014adb6632c5b10c6d5b6f97b8d1250f6e409e11c01630240c7004022db674ff2961b540d4edab846d550429ae9a92311ba375a4f452331422961fdcde3bf79631755dd12df409e24a849158d4aeab919cab81520fb7d1e02204f089176a5bca95ec9227b8a87dfec947c59453805bf46d3f5a18f8032255b5a0161015f560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd9cc5b191f3190101160014dcfd9b78c24260823e318153665d511d6c4ecb1b6302406b75ef5a9decfa31d4f5ae06e0fb14ca507ba4a03715874d1d831516945121573b9b858e4d7527d209c1f89f74e0aa4c4e38afd098cbadaff31b9107167099012067512f9250f559699e32c72c8af29096b1556af145f6ecc0c306e6acc88bbfaa03013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0ebbcde02011600147a9baebd37dba3f14960624ed8e6ca3cc9d5f73800013e608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cdb8c4b191f31901160014f0370fdf7a7bec7b34cc62fd5291071a3dc3d9b0000147608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd6401246a2277656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c00"
    + |7 U9 e/ F& c' `9 P7 o3 ~, w- V  }
    , R! F) _: s( @2 T# N响应参数:
    ; Z8 u. z8 i; J4 i {
    $ X; ?) E4 f5 }7 W5 m8 N"status": "success",# a" D8 y6 `7 R2 y2 x4 I! A$ u
    "data": {  Q: _/ J# O$ o$ Q0 B! N' m
        "tx_id": "5ef27b930646d468bbb436d3406972ff201aa63702518f777e31dd6a2147dddc": M. ^' ?; x- j" W# B
      }
    0 A* D# `3 j, a. r) [}  [: `5 u. `! ~; Y% P
    6 K2 k4 Z5 @* V; w
    用上面返回的tx_id去比原的浏览器中去查看交易详情,就可以查看到我们上传的数据
    3 `! a' P  d6 a3 G0 \) b% c! Z/ d9 y3 t% I# t5 m8 y6 \
    参考代码:
    7 H; I4 @4 t6 @7 ipackage main
    , x, F0 `, W) ?$ Bimport (
    6 A/ {- R; V6 D" C# d* V"bytes": @( ~& b; O- |2 ]% n
    "encoding/json"
    # j- ?5 O5 P+ v. I0 t. \5 E6 t"fmt"8 O4 F+ T6 X1 `4 Q, F2 a* ~
    "io/ioutil"! G. U: r6 [. n5 s9 }6 z& P6 b  B
    "net/http"
    , J$ i, U" N" {# F)
    + n, u1 ]6 v: X( c//build-transaction params' j* i  A7 ~3 V. B% z0 m1 F
    //https://bytom.github.io/mydoc_RPC_call.cn.html#build-transaction2 }0 I. Z: k9 M, F/ \- t0 R
    type BytomAccount struct {# [" B$ x3 E4 P$ w0 {$ D# t# @9 v! a
    AccountId string `json:"account_id"`
    " Y+ @0 Z8 m4 N* DAmount    int    `json:"amount"`
    ( h% g2 Y) M3 g/ D2 t) R3 fAssetId   string `json:"asset_id"`
    : e5 G; u9 Z8 B+ _//Arbitrary string `json:"arbitrary"`' x* S- v7 c. y
    Type string `json:"type"`6 G& o/ G; A. B8 s7 d
    }: y% A0 R) p9 a
    type BytomAccount1 struct {
    1 L# X7 k, y% w0 DAccountId string `json:"account_id"`! \0 H3 G+ V& f
    Amount    int    `json:"amount"`% }% _& t" x( z1 N  ~( j
    AssetId   string `json:"asset_id"`
    8 i% K. j6 \2 q0 qArbitrary string `json:"arbitrary"`
    1 H, g0 r. n# w: eType      string `json:"type"`9 d- y$ _2 a/ q
    }
    1 j2 T) J* {' U6 ^1 @& N* ytype BaseTransaction struct{}
    ! }5 h. K6 _  a3 q5 [9 f% b& Ptype TransactionParams struct {
      W' B2 ^2 G1 I2 Y; i3 l  rBaseTransaction *BaseTransaction `json:"base_transaction"`
    5 j& d' o* c& t: Q+ j* LActions         []interface{}    `json:"actions"`' _- u1 U  ~/ c, o/ I5 p
    Ttl             int              `json:"ttl"`+ _2 P3 I2 {/ `6 W1 a. z
    TimeRange       int              `json:"time_range"`4 Y! h5 H$ n) ?
    }8 C% ?$ M- u3 @0 \- G( P& t4 n
    //sign-transaction params1 n' p! k! I6 m2 z) ~3 }: v9 ~: v$ w
    //https://bytom.github.io/mydoc_RPC_call.cn.html#build-transaction" U7 P, ]3 W  k# z; _( @
    type Transaction struct {
    % {( Y1 k0 `& u5 M}1 Z. R$ B% p% M/ k
    type SignParams struct {
    0 I* i/ _5 ?: c0 t- S) o; C' PPassword    string      `json:"password"`6 a6 d5 f. l- g1 `3 l5 T$ J
    Transaction Transaction `json:"transaction"`& G# w! A! c: O: W
    }
    " S: T- ]) [& x: O4 M: V//submit-transaction) t6 r+ v9 m. [! n( C% O0 W) N
    //https://bytom.github.io/mydoc_RPC_call.cn.html#build-transaction
    ; Q  A$ J' ~+ y3 ptype SubmitParams struct {
    ) T! G% Z# [1 z. V7 Y1 eRawTransaction string `json:"raw_transaction"`- y: a+ f* }' h; n3 w' M
    }0 ?# _! A2 l5 b5 D( u3 b  A
    type SubmitResponse struct {
      o9 _" \, d* ]' R9 B' bTxId string `json:"tx_id"`3 a$ b9 M% R$ ~/ I( [" C2 b" b  n
    }& Z8 u, u, _6 o/ p! z  n
    func main() {: R4 J% i9 T( D* z+ {
    account1, account2, account3 := BytomAccount{}, BytomAccount{}, BytomAccount1{}
    2 D6 d& V( B. \! zaccount1.AccountId = "0KTCS3R5G0A02"
    ( K. a! I  Z" Z' o' p; R* m1 W5 Iaccount1.Amount = 10000000
    6 n! W0 P7 f& x; i. `account1.AssetId = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
    ! v6 a* J  b( h& A8 I: Haccount1.Type = "spend_account"
    $ _* }( n- L- ]# waccount2.AccountId = "0KTCS3R5G0A02"- N) Z  x0 i& e- I; G
    account2.Amount = 100
    0 i" b8 O' R( m5 R) i+ F4 N. D4 @account2.AssetId = "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd"
    ( x  J8 r+ I% J4 l$ A- g5 K/ Z, ]account2.Type = "spend_account"/ s  D' g  V" C/ r' G. D
    account3.AccountId = "0KTCS3R5G0A02"
    " z) U6 Q3 w" W. b- gaccount3.Amount = 100
    0 G0 ~% K0 d" ~7 W6 i0 S: V( A! F8 \account3.AssetId = "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd"$ {, {5 H# U% G
    account3.Arbitrary = "77656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c"
    6 V# x8 R7 y) G, zaccount3.Type = "retire"
    ! T+ S$ ^& [4 H  B) J! i( @//var array
    - l7 D% C2 Z  Svar actions []interface{}; d$ @; T9 O+ N; \) [
    //append three params
    7 e# [( F3 b' L4 r" c9 `3 c5 narray_actions := append(actions, account1, account2, account3)
    , k9 i2 [% Q- I6 ktransaction_params := &TransactionParams{}
    4 U8 W& r9 K5 S3 c! stransaction_params.Actions = array_actions
    6 m7 Z* n, A3 T# A) P! Itransaction_params.Ttl = 0
    $ \8 E' }0 V* n0 q! o( ytransaction_params.TimeRange = 1521625823
    : K$ P% F- d( e, l. z3 t//本地测试网节点- k: x4 D: m2 H5 j
    //build-transaction
    / G+ {& k( I( _5 _9 b, i7 Lport := "http://127.0.0.1:9888/build-transaction"4 b- Q8 z$ y! u: C9 \9 O$ A
    value, err := SendTransactionRetire(transaction_params, port)% i% `: Q( \+ }. d1 L- |" u1 _
    if err != nil {& |/ h, C& V. U" S( B7 m; |; u
            fmt.Println("err:", err)
    % E8 h! ^6 E; u+ R}
      G1 V+ o* U0 I' F- E, ofmt.Println("build-transaction接口返回的参数:", value)2 Y5 ^4 Q' ]# n
    //sign-transaction
    " V* N! t0 r, q- m8 c4 f) N//...........
    " `. x% V/ Q0 |- u//submit-transaction# g4 K% c7 v5 a4 X
    //...........
    5 J9 \6 o, H0 q& p5 s}7 d! Z+ J6 Q; D
    //send post request# s# B2 x7 N" l! Z% w) ^6 s
    func SendTransactionRetire(params *TransactionParams, port   string) (v interface{}, err error) {% c4 `* m/ }8 X: w6 P
    //以本地测试网节点连接* s  y2 r- J" `. n5 x$ @8 M2 c
    ParamsStr, err := json.Marshal(params)
    5 Y( `" u  m; Y6 P& m% Z  |  Oif err != nil {
    1 e- c& F. l. K+ N        return nil, err
    3 c3 d* ?( Y- p, I1 h) _}
    1 J7 ^: C& l, F& QjsonStr := bytes.NewBuffer(ParamsStr)
    $ w! I/ j) Z* ]$ s2 A6 x' ]0 ]fmt.Println(jsonStr)
    ( o; P+ O* e1 Sreq, err := http.NewRequest("POST", port, jsonStr)
    ( k# C, e) Z, G5 `) Xreq.Header.Set("Content-Type", "application/json")
    8 C4 c6 K6 m! k4 b6 t# qreq.Header.Add("Accept", "application/json")
    # V8 G2 A! D/ R7 f. M5 U/ ^client := &http.Client{}
    , q4 @$ b, w& qresp, err := client.Do(req)
    % J  j- B0 K1 e, Q& \7 Q6 P# N0 Hif err != nil {
    + s! m  U& x2 P0 l! J        panic(err)
    " D4 t6 g$ ?# a9 D0 g- z}- K+ C# p( s, j' l& }. [
    defer resp.Body.Close()
    + E6 j6 [' M! A8 i) F, N7 Z% kvar bodyBytes []byte& i9 W8 o, E% {" l9 I4 R
    if resp.StatusCode == 200 {: C. s  j! l' J
            bodyBytes, err = ioutil.ReadAll(resp.Body)
    ' E' U" `! [3 k& L$ B) M# ?        if err != nil {1 @' F9 N2 D- F6 ?' F
                    return nil, err% b9 g  ]+ }, Z4 ~3 S* y
            }8 }# X3 ~+ f; h7 _4 P7 q
    }% Y, a3 Q# B7 U
    return string(bodyBytes), nil
    + I( R( ~3 t  ~( Y}. I$ b+ P4 i* r8 \8 X4 D
    上面的代码只是build-transaction一个步骤,另外sign-transaction和submit-transaction请求需要自己去组织参数进行请求。请求完submit-transaction 获得返回的交易hash,去区块链浏览器上查看自己的上链信息,区块链浏览器地址:http://52.82.46.157:8082/。
    # m7 }; f- y- `2 g: N好了,通过以上的4个步骤,我们就可以借助比原链实现信息上链。如果你有什么疑问或者不明白,请在我们的社区联系我们,https://github.com/Bytom/bytom。
  • BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
    声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    成为第一个吐槽的人

    wzls3146 小学生
    • 粉丝

      0

    • 关注

      0

    • 主题

      1