Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

wzls3146
279 0 0
很多了解比原链的都知道,比原链是专注信息和数字资产在链上交互和流转的公链项目,信息上链不是比原链核心能力,所以并没有在钱包端做一个功能入口,但是比原链提供了相关的接口可以将一些信息写到链上去。
" W/ Q: L) ~- u# N$ \+ B那如何实现信息上链呢?使用特殊的Retire操作,这个操作可以进行销毁资产的操作,但因为其可以附带信息,所以就可以实现信息上链的功能。* V9 K7 b% i# u5 p9 a
请往下看,也用postman请求演示,然后用golang写了一个接口的demo, 在用golang代码实现之前,我们先要做一些准备工作。' c9 l3 Y/ w( A; |
  • 首先确保自己在本地已经搭建好了比原的节点,如果你还没有搭建好节点,请参考开发文档:https://docs.bytom.io/mydoc_build_environment.cn.html
  • 确保自己账户是有足够BTM测试币,如果没有可以去比原链水龙头领取BTM测试币,领取地址:9 i. y' I: h0 x3 q% q

    1 o: Y7 S- \3 h# Dhttp://test.blockmeta.com/faucet.php3 I2 n5 h; _: F! f( x4 y. ?9 u* ]1 _
  • 发行自己的资产,参考:https://bbs.8btc.com/forum.php?mod=viewthread&tid=242940&extra=
  • 信息上链的本质就是其实就是创建并发送一笔交易,我们都知道通过api发起交易主要有三个步骤,先 build → sign → submit,分别对应的api是 build-transaction、sign-transaction、submit-transaction。用postman请求过程如下:
    ! I6 h. ^9 V* I1 T( k% C

    ' J/ w$ z; K% P$ d  t9 Z7 `8 D: w& `- _请求build-transaction接口:1 b: ]% W2 ~( F, M

    # S1 s; j+ \5 }( R' d1 X% i请求参数:1 p3 \( K9 g6 q' B  {; }6 p7 k
    {) l% Z, J1 |7 o# o: L" G
    "base_transaction": null,
      P* Y) v: H; a3 b1 G"actions": [{
    ( Z) Y5 W9 N; @- O0 I/ }$ y* T7 X7 L6 F        "account_id": "0KTCS3R5G0A02",  Q1 x  }% N: o+ E7 h/ e
            "amount": 10000000,% P! v; ]% _. `' ~' O' v
            "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",' Q% h" T- @; e& M; `
            "type": "spend_account"9 G3 t! u0 j6 A" M. X
    }, {
    2 X* w5 H' R8 V& |        "account_id": "0KTCS3R5G0A02",
    - f6 C9 G9 C: |. k0 I+ |        "amount": 100,
    3 C& g6 N1 Q% ~  @$ D0 ~        "asset_id": "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd",5 z( Z/ V. W5 R% N6 {
            "type": "spend_account"
    3 N  s! m5 ]" Q+ t# ~* C; v. t% J! b}, {! S) s' V- n5 _; x! P
            "account_id": "0KTCS3R5G0A02",0 v7 u6 z, ~. x; j9 _
            "amount": 100,
    * ~+ x* C  R" z0 |1 Y        "asset_id": "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd",
    % X! g, V. |/ X" Z# P        "arbitrary": "77656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c",5 A, ?  i9 _* a8 ?) J2 ^
            "type": "retire"
    # `% b, ^6 x: J$ G: j' @}],
    - \% N8 K5 D: y% s5 Q, H; f"ttl": 0,2 [, O( P" w- @5 @) F" n$ _& |
    "time_range": 1521625823- y# E! ^  v9 M8 L) b9 k, H' D
    }
    4 Y$ H/ }5 B5 z4 ?请求sign-transaction接口:: R% P8 d3 O, T4 k# Z" {6 F6 p

    # b2 y5 A0 f. j+ F8 L- T% d请求参数:) \% O, r1 S5 {4 |" h% W3 E
    {0 r% R; a! q( ~: a" r7 w/ r4 B7 ?6 ]
    "password": "huangxinglong123",8 O; O( x! R  @) j2 w! ^, e
    "transaction": {
    % ?) w9 K: Q# s/ _6 X1 M) a: d        "allow_additional_actions": false,+ o$ k0 f( k* ]5 r% d; b
            "local": true,' _. b9 {" T2 @) p' t
            "raw_transaction": "0701dfd5c8d505020160015e560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0989fe3020001160014adb6632c5b10c6d5b6f97b8d1250f6e409e11c0101000161015f560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd9cc5b191f3190101160014dcfd9b78c24260823e318153665d511d6c4ecb1b010003013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0ebbcde02011600147a9baebd37dba3f14960624ed8e6ca3cc9d5f73800013e608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cdb8c4b191f31901160014f0370fdf7a7bec7b34cc62fd5291071a3dc3d9b0000147608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd6401246a2277656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c00",7 `' [& N2 V% ]' P; |) B
            "signing_instructions": [{6 l3 Q7 w+ p, I9 n. `8 R
                    "position": 0,+ P$ c: i5 F1 G, O
                    "witness_components": [{
    ; ~6 K6 c5 r' C0 X4 D. g                        "keys": [{' c: }+ L/ i2 N& Y  I
                                    "derivation_path": [: H3 Z6 c8 C/ J* K
                                            "0000002c",! U9 y7 ]7 e5 Q! _0 K
                                            "00000099",
    - E/ Z: M. k" Q$ p  d, y; }                                        "0100000000000000",, R' w/ k/ ?" I* D
                                            "0100000000000000",- w6 ?$ l  O4 W) y$ L7 J$ A/ `
                                            "4600000000000000"
    & Z% y7 m4 l8 ~- ~! z                                ],
    1 U' @+ y0 w/ ^1 |( ^                                "xpub": "1c03161a08a4dbb7df153815a28f733fec1ac7579f954c4834e5ce9f0ad8deb260ecb2066a8623b69aa936f5798f4dcb9572bc476f2c8171953ce054d58a759f": `" {, h% Z" M7 x& S8 G8 N
                            }],
    % ^* A+ R7 b' [9 X( o; [; c- E                        "quorum": 1,
    ) G  G7 \- D$ A0 s; F5 n8 O                        "signatures": null,
    3 Z0 f2 ]2 G/ ]: O5 U                        "type": "raw_tx_signature"/ l) ?9 {+ P5 A" A
                    }, {
    0 u6 q7 \+ [3 H, z, m7 g- \                        "type": "data",
    6 m& R. g7 y+ a                        "value": "4f089176a5bca95ec9227b8a87dfec947c59453805bf46d3f5a18f8032255b5a"
    9 }. P+ U! R9 D5 n3 z. b; m7 v5 j2 |7 E                }]
    + c2 E) ^, j' F# M  s+ Q6 {# J        }, {
    : l! A( |* T8 X7 R. e( ^+ e/ y% V                "position": 1,- N5 a4 u( Q) [
                    "witness_components": [{
    6 _2 ?9 G8 r6 w6 y                        "keys": [{. q! t: E1 [/ |- p: O+ ~5 {2 }& t0 C
                                    "derivation_path": [, a3 ?  ^0 s9 K8 c+ |( l' g
                                            "0000002c",
    9 Z, B" Q: W4 L: `- J: B                                        "00000099",
    ' J. x) L! z- G+ }3 e; ^                                        "0100000000000000",
    4 y" ^: y; T1 q8 q) F' L                                        "0100000000000000",3 x" N; Z6 r+ D2 Z4 P
                                            "4700000000000000"
    # j' h; Z9 t; O- y                                ],
    7 ?3 M/ R; q) c1 E8 _                                "xpub": "1c03161a08a4dbb7df153815a28f733fec1ac7579f954c4834e5ce9f0ad8deb260ecb2066a8623b69aa936f5798f4dcb9572bc476f2c8171953ce054d58a759f"
    8 ~% j6 [8 f* Y7 ?, c+ `                        }],
    6 n3 N3 q1 x' P4 l                        "quorum": 1,
    3 X" e. W' ]# D4 K# ]. B  A& @                        "signatures": null,9 ?7 S- c) `: i. o
                            "type": "raw_tx_signature"1 N% K8 P+ ^, N  F% w2 s! [
                    }, {' h) S$ Q! F. i) x, b
                            "type": "data",
    7 h+ x. I- w* O                        "value": "67512f9250f559699e32c72c8af29096b1556af145f6ecc0c306e6acc88bbfaa"  m, S# w( @  q% T/ W
                    }]( X6 w' F% |* n  V
            }]
    & T  |( n  o# k4 Q, ^0 O. z}
    0 L+ T& Z, y; ^( A+ R1 c}4 p" F3 r' B5 _7 I5 Y4 p% e
    请求submit-transaction接口:1 [- w) |, t( Y, Z/ _8 d/ b* {
    ( C, S0 b. z& j6 A
    请求参数:
      i6 E- `4 z$ ^6 I3 v2 x  y/ a {/ N, ?+ x4 [9 ~  [0 ^4 y8 q/ @0 P5 S
    "raw_transaction": "0701dfd5c8d505020160015e560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0989fe3020001160014adb6632c5b10c6d5b6f97b8d1250f6e409e11c01630240c7004022db674ff2961b540d4edab846d550429ae9a92311ba375a4f452331422961fdcde3bf79631755dd12df409e24a849158d4aeab919cab81520fb7d1e02204f089176a5bca95ec9227b8a87dfec947c59453805bf46d3f5a18f8032255b5a0161015f560352e415b41be7648b2241ffdabf56259bc618525f62ac123dce32002110f0608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd9cc5b191f3190101160014dcfd9b78c24260823e318153665d511d6c4ecb1b6302406b75ef5a9decfa31d4f5ae06e0fb14ca507ba4a03715874d1d831516945121573b9b858e4d7527d209c1f89f74e0aa4c4e38afd098cbadaff31b9107167099012067512f9250f559699e32c72c8af29096b1556af145f6ecc0c306e6acc88bbfaa03013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0ebbcde02011600147a9baebd37dba3f14960624ed8e6ca3cc9d5f73800013e608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cdb8c4b191f31901160014f0370fdf7a7bec7b34cc62fd5291071a3dc3d9b0000147608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd6401246a2277656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c00"  [2 y* s6 P# s" I! r9 ?
      }
    6 r% e. R, T* x$ L响应参数:
    8 Y, M9 j& J8 F! n5 U$ M5 H  F& N {
    - A3 _/ }# b0 ^0 G4 U, i& F1 f"status": "success",
    6 K& }6 M' l: K" R( f"data": {
    , T5 O+ H& c2 c, G+ _    "tx_id": "5ef27b930646d468bbb436d3406972ff201aa63702518f777e31dd6a2147dddc"% p8 M- R' R7 _
      }
    % k5 n4 Z1 \- g; Z}
    , ]+ ^) n* w; M1 ~8 Z/ ?5 E2 Y$ [' p6 T
    用上面返回的tx_id去比原的浏览器中去查看交易详情,就可以查看到我们上传的数据+ Z! m; ~  p# k

    / {9 B3 D! A" a4 G参考代码:; ~. L& |( }  T4 @% o  H
    package main
    / n6 C7 o9 N& ]. K4 Limport (5 S8 J* |+ A) g6 ^; O+ m$ l! F
    "bytes"
    % b' G% w- }2 ]  D. N"encoding/json"
    % n) ~. t; q/ q4 m"fmt"
    5 g, c6 B9 I; I/ m"io/ioutil"
    5 o2 V( s# M% N& p! k' ?"net/http"
    0 u( a" C6 M3 U4 r3 }; y3 N)
    - }; Z& z' I! D( ~' ^* n//build-transaction params
    6 e* a: ^7 i9 B* O2 f//https://bytom.github.io/mydoc_RPC_call.cn.html#build-transaction* k- V4 b9 ~- u+ i+ X" J) f% C
    type BytomAccount struct {& A" w/ W/ g: S+ x
    AccountId string `json:"account_id"`
    1 G# w% h+ [. x: K+ U: b& m! hAmount    int    `json:"amount"`% y4 \4 z" i& p$ c* E6 c
    AssetId   string `json:"asset_id"`% h% Q  S6 _5 ?  F9 ]3 z! B! a
    //Arbitrary string `json:"arbitrary"`
    : j. d7 f1 P9 o$ `: X4 L, G9 mType string `json:"type"`
    5 v. }% \1 p$ F9 W9 X& ~}
    * f7 Z% s, }5 n* m/ ~9 Z8 R) |type BytomAccount1 struct {. o5 f8 g' N' j
    AccountId string `json:"account_id"`" J3 K' R3 ?. ~1 W+ @0 P* x
    Amount    int    `json:"amount"`
    * Z4 L' w' u0 ^: [  i  f( l2 x. JAssetId   string `json:"asset_id"`
    $ W' P/ K3 h4 K; W* Z5 }Arbitrary string `json:"arbitrary"`
    % D2 {( ]: ]8 [3 f8 HType      string `json:"type"`
    5 c; {( ]& b, p/ }3 |}
    . P: D" c  q8 n8 z4 N/ A5 Mtype BaseTransaction struct{}& U  [2 I! o' X* Q: f- R! \2 e
    type TransactionParams struct {; {4 W  l; j9 n) o$ {
    BaseTransaction *BaseTransaction `json:"base_transaction"`
    # m4 R- o+ _  Y$ |# kActions         []interface{}    `json:"actions"`# W+ z3 `4 f, S6 b
    Ttl             int              `json:"ttl"`
    , h0 S8 G. H; BTimeRange       int              `json:"time_range"`0 U$ j& ~9 G; r0 D
    }
    : T2 W8 N8 M  y( m0 g$ L) k//sign-transaction params5 P4 ?# F- E  g. U2 t  d( c/ |  S
    //https://bytom.github.io/mydoc_RPC_call.cn.html#build-transaction, J; r! u$ |: r7 x8 x7 B
    type Transaction struct {/ k1 Z, n4 Y2 ^  S2 O) P. S
    }
    ; t4 y  d& y$ r$ ]type SignParams struct {
    ) o  |9 d  {& ?8 ?3 A' t! S0 _8 sPassword    string      `json:"password"`
    3 Y/ c% Z: g2 L( F  g# WTransaction Transaction `json:"transaction"`) u7 ~4 a5 Q( p/ R# p0 w: I
    }
    ' j6 r, Y: I1 s$ h4 q+ W) o6 u//submit-transaction
    ! {6 \- u$ [- Z4 a1 z3 D( d3 u) E//https://bytom.github.io/mydoc_RPC_call.cn.html#build-transaction
    # s% F) _3 R+ l7 L4 Mtype SubmitParams struct {  [. A+ G) \' T8 U
    RawTransaction string `json:"raw_transaction"`! ~1 H: O6 Z' t- A
    }
    * E5 k1 `, s# h, m4 ~# ztype SubmitResponse struct {
    7 o5 C) z/ h. R- o, T! j+ p) PTxId string `json:"tx_id"`
    $ C9 o' e1 C' e}9 E# x' \9 y5 k" h" V
    func main() {
    . X, [, j/ p9 |account1, account2, account3 := BytomAccount{}, BytomAccount{}, BytomAccount1{}( G! m% s8 l! _% a: _3 ]
    account1.AccountId = "0KTCS3R5G0A02"
    % G8 N# Q% @, W# A' x0 |account1.Amount = 100000008 k5 j9 i# ?, A9 ?5 c3 c
    account1.AssetId = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"" ~9 L1 N( M4 I0 a# g0 Z
    account1.Type = "spend_account"0 R5 e. @  W5 e+ x1 ?" \
    account2.AccountId = "0KTCS3R5G0A02"1 r9 F3 q* V9 Z- Y% i# ?: f
    account2.Amount = 100
    $ s2 v8 S/ n, p" t" Taccount2.AssetId = "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd"4 i, |, v, }; v, E  R
    account2.Type = "spend_account"- l# H9 H" i# D
    account3.AccountId = "0KTCS3R5G0A02"
    ) L. U1 y* u0 r* F# Taccount3.Amount = 100& u2 l8 o( j% l' t% n
    account3.AssetId = "608037f96e8d1613d900c67a0730cc90e2a03311fb7d091588f7eb551a6103cd"! q4 M/ b) [# Z4 N8 t6 o
    account3.Arbitrary = "77656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c") K3 @0 j7 N9 o: p5 K
    account3.Type = "retire"5 Z$ d! E% K0 e, W0 m! n1 N8 S
    //var array: j; J/ {" _  \, l4 Q( M, j) i
    var actions []interface{}
    : H# ~/ @5 K, N7 p8 t9 h//append three params
    6 m( C9 G. Y5 farray_actions := append(actions, account1, account2, account3)
    8 n  N, z" e, q$ M1 ~7 V) Dtransaction_params := &TransactionParams{}' @) Y( B  h1 L# w* [# Q
    transaction_params.Actions = array_actions
    # |4 Y8 W, r4 M" \0 M1 b  Mtransaction_params.Ttl = 00 f  l1 X6 l1 U; Z9 \# Z( _' P
    transaction_params.TimeRange = 15216258234 q* j- K( ]  m; l: L1 \/ X
    //本地测试网节点0 X  u- @  J3 ?( [: c4 K6 J
    //build-transaction; M/ b$ [5 w! F3 Q6 J( K8 x/ ?/ R
    port := "http://127.0.0.1:9888/build-transaction"
    / C3 w/ G5 C# I  Y9 l, C: Fvalue, err := SendTransactionRetire(transaction_params, port)
    7 p  ^; n: t5 \% ~& U: `; yif err != nil {
    ! O+ q/ |" w: ?3 r$ c3 h" ^8 ~        fmt.Println("err:", err)
    0 ?' Z( c* ~9 N7 v}
    # T2 h- ~$ d  u% q; e* Y2 g' b7 Afmt.Println("build-transaction接口返回的参数:", value)
    " I# `' z8 V& x1 B9 s//sign-transaction
    " }0 c- Y8 j5 J  T//...........
    ; Q, _- [  H0 x0 P  w) ]- I7 ^//submit-transaction
    , D9 h& O) M- t& a/ L& T, @//...........
    + q- X3 R* h( ?5 e% n1 B}
    3 A$ j2 c& M% q7 G1 y- s//send post request
    , M0 f. e/ m6 [4 K; K& x7 |/ Jfunc SendTransactionRetire(params *TransactionParams, port   string) (v interface{}, err error) {
    1 E& u; u& I& \, C! D//以本地测试网节点连接+ R7 C# _2 P: h, e
    ParamsStr, err := json.Marshal(params)% b5 a0 W& ~/ L0 g; l4 K
    if err != nil {( G" H; m2 Q1 m
            return nil, err
    & o2 t# U2 K3 b+ g" _* O, x. c}
    ! B* W. U6 }8 qjsonStr := bytes.NewBuffer(ParamsStr)' h+ o0 I. s  z; g# q
    fmt.Println(jsonStr)
    7 G' z1 C" Z/ G( ureq, err := http.NewRequest("POST", port, jsonStr)
    ; K' D  \) Q! |. m* Zreq.Header.Set("Content-Type", "application/json")
    " g- y. t8 p1 \+ k; D1 treq.Header.Add("Accept", "application/json")5 G# m3 j6 C( \* y' J8 [
    client := &http.Client{}8 x6 K; [) K! f8 e8 S$ R
    resp, err := client.Do(req)4 N, \5 I, T+ r$ Z
    if err != nil {+ }9 D0 D' B: w  W7 p8 U1 H
            panic(err)
      x5 r! |7 y1 r9 [4 X9 s6 T}
    $ q3 A0 C" U+ @7 s7 f, X  x" X9 Ddefer resp.Body.Close()
    2 C$ x. c- M# x3 H/ k/ u& f) Hvar bodyBytes []byte
    8 V0 @3 X9 ~% N1 Wif resp.StatusCode == 200 {
    * S+ o$ @8 O. E# ?* F$ V# L3 T        bodyBytes, err = ioutil.ReadAll(resp.Body)9 g1 a8 K; ?; r, Q6 e
            if err != nil {
    , |2 W2 S; J- N2 C4 }) g5 f                return nil, err
    ! |7 ]+ G6 a- C" m        }- p7 _6 `5 w( O
    }; L0 v% ^2 z& p
    return string(bodyBytes), nil) f" P  s( g/ n3 |
    }" U* k: }. m0 M7 q* T; Y
    上面的代码只是build-transaction一个步骤,另外sign-transaction和submit-transaction请求需要自己去组织参数进行请求。请求完submit-transaction 获得返回的交易hash,去区块链浏览器上查看自己的上链信息,区块链浏览器地址:http://52.82.46.157:8082/。  A- v# {  n0 D) t. r) Z7 U' L) Z9 p
    好了,通过以上的4个步骤,我们就可以借助比原链实现信息上链。如果你有什么疑问或者不明白,请在我们的社区联系我们,https://github.com/Bytom/bytom。
  • BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
    声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    成为第一个吐槽的人

    wzls3146 小学生
    • 粉丝

      0

    • 关注

      0

    • 主题

      1