Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

wzls3146
327 0 0
很多了解比原链的都知道,比原链是专注信息和数字资产在链上交互和流转的公链项目,信息上链不是比原链核心能力,所以并没有在钱包端做一个功能入口,但是比原链提供了相关的接口可以将一些信息写到链上去。# U5 |9 \+ u* B! x
那如何实现信息上链呢?使用特殊的Retire操作,这个操作可以进行销毁资产的操作,但因为其可以附带信息,所以就可以实现信息上链的功能。
8 S9 M5 e9 a) h" Q4 ]7 Y; {+ |请往下看,也用postman请求演示,然后用golang写了一个接口的demo, 在用golang代码实现之前,我们先要做一些准备工作。. c( H3 K+ Y# I& `0 t* E
  • 首先确保自己在本地已经搭建好了比原的节点,如果你还没有搭建好节点,请参考开发文档:https://docs.bytom.io/mydoc_build_environment.cn.html
  • 确保自己账户是有足够BTM测试币,如果没有可以去比原链水龙头领取BTM测试币,领取地址:
    ; t! }3 {, |: l

    . A4 h$ r9 g, y  Mhttp://test.blockmeta.com/faucet.php, t# \) _2 n+ a& B
  • 发行自己的资产,参考:https://bbs.8btc.com/forum.php?mod=viewthread&tid=242940&extra=
  • 信息上链的本质就是其实就是创建并发送一笔交易,我们都知道通过api发起交易主要有三个步骤,先 build → sign → submit,分别对应的api是 build-transaction、sign-transaction、submit-transaction。用postman请求过程如下:
    + e# k4 v- ]2 P: S3 ]

    8 h, E' H, w& e9 G" P; M请求build-transaction接口:% \8 S3 M1 u* B3 [3 H# v- ~

    ( c3 \* P9 U$ Y  b1 b9 L9 D请求参数:  A" p+ T' r) k- z
    {; i1 F. \: K6 [- Y  {( t
    "base_transaction": null,
    7 B& i: A& N# z9 F4 G& Q0 u' E"actions": [{9 T9 M7 Y# `" O/ t. |% ]
            "account_id": "0KTCS3R5G0A02",) n+ N* V) O! `( s. D( J
            "amount": 10000000," K/ H& `6 a! X* s1 r
            "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",+ k8 \+ I' o& G3 O' v8 J! U  m
            "type": "spend_account"( b* {2 j8 ], E9 F( v8 T
    }, {5 I9 b- ]9 u3 b+ R0 ~
            "account_id": "0KTCS3R5G0A02",
    7 J. B  E6 c( y: e        "amount": 100,; e3 g3 ~4 r( a+ J! J2 E1 f$ |
            "asset_id": "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd",
    : m1 |9 v/ |! v- T% P5 V# Z        "type": "spend_account"
    # X  m  j* O; I8 U& K8 Y0 ~}, {7 O" C: U# q* Y& B  z$ ?* V* y0 i
            "account_id": "0KTCS3R5G0A02",
    $ F% \: G5 \* H' }        "amount": 100,
    9 `( Q& o( M9 y, S1 l        "asset_id": "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd",
    / k( Y! L. X1 {/ ]$ i        "arbitrary": "77656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c",
    : {: G5 w9 F+ l2 f6 O% X        "type": "retire"3 U6 ?( L3 R$ r( m: A4 m0 h
    }],
    # R4 _5 A. N  ]/ o+ d  ~"ttl": 0,3 P" m7 J3 u; l2 |, G
    "time_range": 1521625823
    $ r, p# a0 ~. P6 R: z4 h! O9 y1 N}
    0 ?2 P+ T3 X7 F6 g请求sign-transaction接口:4 c- d7 x4 I2 G* s
    4 {  |% c  E4 _; R2 w
    请求参数:) h0 C% \+ {. P+ f+ Y9 }
    {/ I: G9 W% e* f7 g1 Z) }8 l, R
    "password": "huangxinglong123",
    # K4 l0 B6 d2 y8 ~"transaction": {: g. L! Y; I1 |0 ?
            "allow_additional_actions": false,
    # d( a% ^& c* B) Q8 X& r' O; T        "local": true,5 O& R+ k9 U1 J$ C" E
            "raw_transaction": "0701dfd5c8d505020160015e560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0989fe3020001160014adb6632c5b10c6d5b6f97b8d1250f6e409e11c0101000161015f560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd9cc5b191f3190101160014dcfd9b78c24260823e318153665d511d6c4ecb1b010003013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0ebbcde02011600147a9baebd37dba3f14960624ed8e6ca3cc9d5f73800013e608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cdb8c4b191f31901160014f0370fdf7a7bec7b34cc62fd5291071a3dc3d9b0000147608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd6401246a2277656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c00",
    ' r+ H5 h9 j( m5 E5 Q        "signing_instructions": [{
    : ?0 y* X, S1 e8 e8 J# R                "position": 0,
    ) d( M9 `7 e/ @6 k! b. K                "witness_components": [{
    ' A# U% V3 P5 D: [  `7 u8 c                        "keys": [{
    ) {7 m+ h% r! e; D7 A                                "derivation_path": [' A( \) `) D9 E) X/ q6 l3 t2 _
                                            "0000002c",
    - F' X5 `* J& T                                        "00000099"," D$ ^5 p( c% ~: C# Y5 s- Y
                                            "0100000000000000",
    # r! Z# `: [( B                                        "0100000000000000",- T0 a! e& L- |# V1 e
                                            "4600000000000000"
    , I4 F6 T- x5 d- i9 B2 {* `                                ],
    * o2 c7 i# y6 B4 q1 p                                "xpub": "1c03161a08a4dbb7df153815a28f733fec1ac7579f954c4834e5ce9f0ad8deb260ecb2066a8623b69aa936f5798f4dcb9572bc476f2c8171953ce054d58a759f"& W% u3 j8 {' L  D
                            }],
    : e% [% U- F) H3 [- q6 W5 B                        "quorum": 1,
    2 k( Y5 R- n% Q- B0 h3 _                        "signatures": null,
    4 ^& b0 K' [! q                        "type": "raw_tx_signature"
    $ J) }6 x! t0 c9 c, r: z                }, {
    & {  J/ H: q2 U3 s0 c  _                        "type": "data",
    & U5 `! Z2 b, E3 s) `3 L; a                        "value": "4f089176a5bca95ec9227b8a87dfec947c59453805bf46d3f5a18f8032255b5a"
    6 s6 C" z) X5 e/ a+ r6 K* d+ m8 b                }]( y7 h* f. q4 s3 }1 j
            }, {
    4 h  N8 v9 x* ^8 x                "position": 1,
    - U4 H# i+ }% a; a                "witness_components": [{
    + L+ I0 {; T4 l7 u) t- p) W                        "keys": [{
    ; J" ^$ W$ _& R- W( h' \3 v                                "derivation_path": [
    % U7 d5 d3 j; S# s                                        "0000002c",8 k$ b  _5 O& f" n' K( K, @' I% t
                                            "00000099",
    ) z1 |8 v0 X# |                                        "0100000000000000",
    ( R3 ]( M+ u* p6 i6 Z; U9 x                                        "0100000000000000",
    ; R% U; x/ z1 ?                                        "4700000000000000"' |' b8 u" y5 C; q
                                    ],- r5 y2 D4 Q9 P
                                    "xpub": "1c03161a08a4dbb7df153815a28f733fec1ac7579f954c4834e5ce9f0ad8deb260ecb2066a8623b69aa936f5798f4dcb9572bc476f2c8171953ce054d58a759f"/ e. l1 Q3 i$ f; C- l
                            }],! n2 \; J$ ]' W# I6 V1 V
                            "quorum": 1,
    8 z, {5 Y2 W! N( ~4 [                        "signatures": null,
    8 |+ Q2 t8 P) ^4 E; Y                        "type": "raw_tx_signature"& m! u- O$ J# L0 E% P4 M9 d1 n2 f
                    }, {
    & D$ ~7 T! i: U# ?' P2 Q% D, ~                        "type": "data",
    5 N( X! c$ F; O                        "value": "67512f9250f559699e32c72c8af29096b1556af145f6ecc0c306e6acc88bbfaa"+ h/ B7 v' R2 L5 Z$ p5 j2 |
                    }]
    * v' e2 u" i: L7 s' B# T9 T        }]
    1 L1 {4 e- v2 n3 w}# t5 e1 t3 G9 h) e/ Y+ O
    }
    ( n) X3 G. o' n/ \请求submit-transaction接口:
    4 x' N0 g1 s" m
    ' u( D& W- v" q+ U请求参数:/ R% J* D. X9 L2 J1 T. D
    {
    5 E! \1 k3 w  T! ]0 d1 L' p "raw_transaction": "0701dfd5c8d505020160015e560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0989fe3020001160014adb6632c5b10c6d5b6f97b8d1250f6e409e11c01630240c7004022db674ff2961b540d4edab846d550429ae9a92311ba375a4f452331422961fdcde3bf79631755dd12df409e24a849158d4aeab919cab81520fb7d1e02204f089176a5bca95ec9227b8a87dfec947c59453805bf46d3f5a18f8032255b5a0161015f560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd9cc5b191f3190101160014dcfd9b78c24260823e318153665d511d6c4ecb1b6302406b75ef5a9decfa31d4f5ae06e0fb14ca507ba4a03715874d1d831516945121573b9b858e4d7527d209c1f89f74e0aa4c4e38afd098cbadaff31b9107167099012067512f9250f559699e32c72c8af29096b1556af145f6ecc0c306e6acc88bbfaa03013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0ebbcde02011600147a9baebd37dba3f14960624ed8e6ca3cc9d5f73800013e608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cdb8c4b191f31901160014f0370fdf7a7bec7b34cc62fd5291071a3dc3d9b0000147608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd6401246a2277656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c00"; T% L# l& n& [! O$ ]
      }
    / [3 P5 y& @- y5 f9 A* b, s. K响应参数:
    % d( W$ A& z% i! Q, m! J {
    * @  J+ k) D7 `4 K9 K9 c"status": "success",; b2 D# E- g9 S: J
    "data": {6 L8 |3 n8 q5 S. q, K& C4 h* B! I/ h
        "tx_id": "5ef27b930646d468bbb436d3406972ff201aa63702518f777e31dd6a2147dddc"  L# C$ b- G& j  G" j
      }$ E( y" E  X+ {
    }8 }# k5 ^/ J5 }: G) v4 m

    7 p1 }8 V4 ^! R5 q* y用上面返回的tx_id去比原的浏览器中去查看交易详情,就可以查看到我们上传的数据
    / b$ V( ~  L: a: o% l2 N- g' }; q. T& w
    参考代码:
    6 F8 A- Z1 g, Y; a- Tpackage main
    5 `4 c8 g2 X- _+ r; C0 ?8 p( Vimport (
    4 l4 _) ~' Z: e9 G5 y: U"bytes"
    * E. L+ t* M1 \"encoding/json"
    4 H  x- ~  A" v6 J"fmt"9 w% G" }, J8 P( Y
    "io/ioutil"( P- I$ l9 B  i( M* L7 q" U8 ^- Y
    "net/http": I! ]: h+ m' R$ L4 t1 @1 V9 b
    ): }# Z5 b2 f5 B5 N3 g% P
    //build-transaction params  ~1 }8 B+ l! u9 l4 a
    //https://bytom.github.io/mydoc_RPC_call.cn.html#build-transaction
    5 G. W& s, ]/ R8 ]2 x& ytype BytomAccount struct {6 j! p2 e, P) X9 |+ u  v  ]
    AccountId string `json:"account_id"`: W. k( h- c1 x) v; N
    Amount    int    `json:"amount"`
    6 G  ~# Q' T9 l+ GAssetId   string `json:"asset_id"`6 N' W/ Q; o  D* }2 t7 }
    //Arbitrary string `json:"arbitrary"`
    # N$ _$ ^. `, F$ c- m/ f' w: HType string `json:"type"`
    ) ]& v  c( v! h2 C}& |( f% p. Y4 K+ Q* E, x
    type BytomAccount1 struct {
    , M) D( K+ T, V0 A. mAccountId string `json:"account_id"`
    * J5 A1 L4 {7 F: F; _& A4 Y  `Amount    int    `json:"amount"`# x* L0 p* `0 u+ t
    AssetId   string `json:"asset_id"`9 n# j5 E' Z9 v9 m2 b. r
    Arbitrary string `json:"arbitrary"`
    6 l1 [! R& I5 a' lType      string `json:"type"`) U# z% x, n2 z- D' q
    }
    0 h' ~# H( g. j* {type BaseTransaction struct{}& }  n, V9 z' a! F
    type TransactionParams struct {/ e" N! G1 w% K! K
    BaseTransaction *BaseTransaction `json:"base_transaction"`$ o$ M( z* w8 x1 c. Z
    Actions         []interface{}    `json:"actions"`
    " X$ T& B; r6 S0 x# k9 ^Ttl             int              `json:"ttl"`" y2 O- |: H7 w* J; g: J! e6 t1 Q
    TimeRange       int              `json:"time_range"`0 e4 Q: A  a6 N7 j7 }
    }& m; l+ Q7 \9 U/ d& M4 M1 ~* s6 I( \
    //sign-transaction params
    6 |& d. K6 d; W( O8 Q//https://bytom.github.io/mydoc_RPC_call.cn.html#build-transaction  P8 B7 v: \. M
    type Transaction struct {
    & w; i8 _  k2 ?3 J& ~6 D}  N. ]( l$ F! \, b& ^
    type SignParams struct {
    ; i3 X, J) m# |0 }1 D0 z4 gPassword    string      `json:"password"`
    / J9 r. O# C# U# |3 Z, a3 dTransaction Transaction `json:"transaction"`
    " O* t, N- ?: [' _}
    4 @) F6 Q4 v, L" K( H//submit-transaction, _; I! q( ~+ f" N
    //https://bytom.github.io/mydoc_RPC_call.cn.html#build-transaction
    & Z' r) L, H0 A7 x) A; etype SubmitParams struct {% B; T0 A" [. v5 h: r4 x8 E; k+ N
    RawTransaction string `json:"raw_transaction"`
    , p3 r( g* K6 K) z}
    ' x+ f' q# X/ H0 `9 R) s% q! \% c5 Rtype SubmitResponse struct {
    9 h8 v2 a1 ?+ o& o6 ~TxId string `json:"tx_id"`* j7 `, I4 R) A
    }" |( b- F- ]: {) m5 f5 w
    func main() {# s- C, F: S( s0 L. L
    account1, account2, account3 := BytomAccount{}, BytomAccount{}, BytomAccount1{}6 s8 }4 `" z+ q8 v- K8 P+ H
    account1.AccountId = "0KTCS3R5G0A02"
    ' ]: J7 `4 k/ [( e" h7 [9 d9 n2 o4 vaccount1.Amount = 10000000/ `0 A+ q2 `, v3 x+ @3 S
    account1.AssetId = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
    / V$ A4 {. j/ Q' a& {. w4 xaccount1.Type = "spend_account"; H" J5 N7 f- K* h& w
    account2.AccountId = "0KTCS3R5G0A02"/ O# Z5 ^; l& Z: N. d/ R8 S% S$ N3 R, d# z
    account2.Amount = 100
    ; R/ C% F0 `6 Paccount2.AssetId = "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd"3 a& G) I* g9 B. f. A9 G
    account2.Type = "spend_account"
    : C  A# M% l- h9 }account3.AccountId = "0KTCS3R5G0A02"
    / C! E* P) R% ~& y) ]" a/ [account3.Amount = 100( |. E0 R8 u/ |" X- }# O
    account3.AssetId = "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd"
    8 }4 Z! b% ?* h; A6 saccount3.Arbitrary = "77656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c"
    " s( D, @5 Z' Q$ Y$ oaccount3.Type = "retire"
    1 e+ X1 z# p0 i3 J& Z! r//var array- j! M  H! `; I2 e2 H( S  k
    var actions []interface{}/ B- F+ H0 v5 n3 t# S
    //append three params
    9 a' J2 g* l) C5 ]- e& P* }array_actions := append(actions, account1, account2, account3)
    3 l; W) `" s( I* |# w8 y% m8 Qtransaction_params := &TransactionParams{}
    2 F/ h2 i4 ?1 O% D& b3 |" c" Qtransaction_params.Actions = array_actions
    ' G7 v$ }$ x! v6 V: m& Ntransaction_params.Ttl = 0
    2 m3 v/ Z5 ^' B; c' F  Ntransaction_params.TimeRange = 15216258238 _1 |3 c6 l& O7 p
    //本地测试网节点  r$ i- S+ i; G/ L& B( m* O( L  D
    //build-transaction3 H3 U6 ?4 A8 T
    port := "http://127.0.0.1:9888/build-transaction"; S, C3 x) R2 m9 o" [" d# Q
    value, err := SendTransactionRetire(transaction_params, port)
    ; Q$ [5 I$ D  |( K9 f) D6 E, Vif err != nil {
    . r: o  p+ Y0 s! Q        fmt.Println("err:", err)
    % a: v$ q$ H* T2 b}
    : G6 [" Z0 j* ~) K/ B. l% pfmt.Println("build-transaction接口返回的参数:", value)( \4 n: z$ w* Y8 [3 a7 f7 e
    //sign-transaction2 U. B8 I* s! u7 S# B
    //...........! f# \2 m3 `3 K$ q8 a* r5 h
    //submit-transaction
    5 N( i, ~: ~$ l5 h8 e//.........../ h2 w4 P2 [2 m, z' G$ H, E2 s: h
    }
    , T0 l% L2 R( u5 |2 H% s//send post request( M; ~( Q& P4 Q% y4 s
    func SendTransactionRetire(params *TransactionParams, port   string) (v interface{}, err error) {* O& H4 ~7 f: I2 N* M6 B0 _6 I% U
    //以本地测试网节点连接
    5 K/ m9 P0 d: C9 EParamsStr, err := json.Marshal(params)
    / r( W) m+ ]0 [) Xif err != nil {
    " J0 N+ w& k; g% I: F+ \1 R        return nil, err3 @3 r  U5 y1 Z( E/ G
    }
    $ C5 D7 r, I3 u! y  X+ m# s% w3 o: KjsonStr := bytes.NewBuffer(ParamsStr), ?; y# L4 f$ h1 o) X2 q0 V1 N
    fmt.Println(jsonStr)2 G2 ~# m. M5 P; k  T1 b* C6 o0 r
    req, err := http.NewRequest("POST", port, jsonStr)
    / p+ D; t5 q9 Oreq.Header.Set("Content-Type", "application/json")# v0 c7 l" Q/ g
    req.Header.Add("Accept", "application/json")
    - i" q! M  {3 n! Z0 @; {client := &http.Client{}
    : Z2 L% H6 O3 u- b: d. v3 mresp, err := client.Do(req)
    . O5 o" a0 ]" T! @if err != nil {
    . M7 e1 f$ N, y0 _, D5 Z! x0 \        panic(err)8 |! B% @& M3 [* y& c6 y& l" w
    }6 |. W) {& }- ]6 {& A2 h
    defer resp.Body.Close()
    2 ?4 E/ u8 P' r2 R5 o& V( zvar bodyBytes []byte
    + g- M* G3 {& l; f/ C, i8 Aif resp.StatusCode == 200 {
    ! h- w0 x% b$ X        bodyBytes, err = ioutil.ReadAll(resp.Body)
    . P% v+ Q' q/ z" u6 p8 j        if err != nil {
    / i$ u5 Q0 s/ W* t! N, I; b4 W                return nil, err$ j7 u' N7 ?; o: }1 u
            }
    3 x; n; U/ G/ N0 {, S" G$ _' E}
    2 p! S4 S: ~/ ?6 W+ Jreturn string(bodyBytes), nil/ _  L" V% w  C7 J+ C
    }# E! C# l- B, i, R0 a
    上面的代码只是build-transaction一个步骤,另外sign-transaction和submit-transaction请求需要自己去组织参数进行请求。请求完submit-transaction 获得返回的交易hash,去区块链浏览器上查看自己的上链信息,区块链浏览器地址:http://52.82.46.157:8082/。4 U5 u, Q; c) I
    好了,通过以上的4个步骤,我们就可以借助比原链实现信息上链。如果你有什么疑问或者不明白,请在我们的社区联系我们,https://github.com/Bytom/bytom。
  • BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
    声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    成为第一个吐槽的人

    wzls3146 小学生
    • 粉丝

      0

    • 关注

      0

    • 主题

      1