简介

这章的内容详细分析一下涉及智能合约Dapp的整个开发流程,注意是涉及只能合约,如果你只要一些基本转BTM功能没有太大意义,本内容补充一下官方提供的 比原链DAPP开发流程,详细实践过好踩到的一些坑,还有一些真正具体的技巧还有经验,个人认为非常有用,起码让开发者可以更快速地去操作。

资料说的储蓄分红合约太复杂了,简单说说逻辑,银行发了一笔股份资产,用合约锁定,用户去触发这个合约的方法,付出了钱兑换了对应份额的股份资产,当达到一定的高度,就可以通过用股份资产兑换回本金与分红(钱+利息)。 里面包含了两个合约~~

整体流程

开发流程分为,1)编写智能合约;2)发合约交易;3)测试解锁合约方法;4)基于插件钱包开发Dapp前端;5)开发后端;

流程貌似非常简单,本人在1,2,3 步浪费了很多时间。其中有些坑踩过接下来介绍一下;

1)编写智能合约,上面提供的 比原链DAPP开发流程,写得很清楚,使用的是equity非常简单,直接下载最新版 用命令 【./equity TradeOffer --instance 】 就能得到一串编译后的合约程序代码,简称智能合约程序。

  1. E:\GoWorks\src\github.com\equity\equity>equity.exe jiedai_6.txt --instance ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 260374 260474 260574 260674 260774 260874 260874 00141ccef16d2ac1ab22baa8acfa1633fdc32df
  2. d55aa b1f38553d95177c53755996baf523da006da977008f069792bb6a2c3b6a253fb
  3. ======= PartLoanCollateral =======
  4. Instantiated program:
  5. 20b1f38553d95177c53755996baf523da006da977008f069792bb6a2c3b6a253fb1600141ccef16d2ac1ab22baa8acfa1633fdc32dfd55aa030afb03030afb0303a6fa030342fa0303def903037af9030316f90320ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  6. ffffff4d2b015b7a76529c641d010000640c0100005c7900a0695c790500f2052a01947600a0695379cd9f5579cda09a916164380000005a95639a00000054798ccd9f5679cda09a916164500000005895639a00000055798ccd9f5779cda09a916164680000005695639a00000056798ccd
  7. 9f5879cda09a916164800000005495639a00000057798ccd9f5979cda09a916164980000005295639a0000005195c3787ca169c3787c9f916164f5000000005e795479515e79c1695178c2516079c16952c3527994c251006079895f79895e79895d79895c79895b79895a79895979895879
  8. 895779895679890274787e008901c07ec1696307010000005e795479515e79c16951c3c2516079c169632b010000587acd9f6900c3c2515c7ac1632b010000755b7aaa5b7a8800c3c2515d7ac1747800c0

2)发合约交易, 先解释一下合约的逻辑,储蓄分红合约太复杂,所以我们用币币交易合约去举例子,

  1. contract TradeOffer(assetRequested: Asset,
  2. amountRequested: Amount,
  3. seller: Program,
  4. cancelKey: PublicKey) locks valueAmount of valueAsset {
  5. clause trade() {
  6. lock amountRequested of assetRequested with seller
  7. unlock valueAmount of valueAsset
  8. }
  9. clause cancel(sellerSig: Signature) {
  10. verify checkTxSig(cancelKey, sellerSig)
  11. unlock valueAmount of valueAsset
  12. }
  13. }

看看智能合约的交易图,方便小白理解:

所以储蓄分红合约一开始肯定要锁定一部分资产,所以必须部署合约交易。那么如何触发呢?

本人通过PC钱包的接口方式去部署合约,具体很多例子可以在智能合约学习文档看到。

PC钱包方式,所有交易都必须三部,build-transaction,sign-transaction,submit-transaction,三个接口。

踩过的坑

  1. 调试智能合约很慢,要等到交易确认才能知道是否成功,而且报错不明显,不知道哪里出问题;

    解决方案:

​ 本地PC钱包solonet模式调试,更改源码,快速出块 difficulty/difficulty.go

  1. func CheckProofOfWork(hash, seed *bc.Hash, bits uint64) bool {
  2. compareHash := tensority.AIHash.Hash(hash, seed)
  3. return HashToBig(compareHash).Cmp(CompactToBig(bits)) <= 0
  4. }

​ 里面那句添加 ||true 如下

  1. return HashToBig(compareHash).Cmp(CompactToBig(bits)) <= 0 || true

一开始没想到这样做,以为很快调试好,搞了三天晚上10点才调试完。

2.智能合约对于除法的支持很不友好,尽量不要用除法,一开始写了一个很复杂的合约,不知道错误,智能逐步改代码快速调试去定位,最后发现 A/B,如果A=B没问题,否则就直接报错,问过官方没有得到合适的回答,我尝试过是存证这种问题,非常坑。

3.程序必须计算好对应结果utxo 流转action的 input、ouput ;如下

  1. {
  2. "base_transaction": null,
  3. "actions": [
  4. {
  5. "output_id": "13fbd1e5df196a1488e85e3b5983e51444c49ef3695df789c9473abb636e0f5c",
  6. "arguments": [
  7. {
  8. "type": "integer",
  9. "raw_data": {
  10. "value": 5500000000
  11. }
  12. }, {
  13. "type": "data",
  14. "raw_data": {
  15. "value": "00141ccef16d2ac1ab22baa8acfa1633fdc32dfd55aa"
  16. }
  17. },
  18. {
  19. "type": "integer",
  20. "raw_data": {
  21. "value": 0
  22. }
  23. }
  24. ],
  25. "type": "spend_account_unspent_output"
  26. },
  27. {
  28. "amount": 5500000000,
  29. "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  30. "control_program": "0014d470cdd1970b58b32c52ecc9e71d795b02c79a65",
  31. "type": "control_program"
  32. },
  33. {
  34. "amount": 5000000000,
  35. "asset_id": "80013f81a66cb99977879e31639bb4fe4b12b4c7050fe518585d3f7f159d26a9",
  36. "control_program": "00141ccef16d2ac1ab22baa8acfa1633fdc32dfd55aa",
  37. "type": "control_program"
  38. },
  39. {
  40. "amount": 9999995000000000,
  41. "asset_id": "80013f81a66cb99977879e31639bb4fe4b12b4c7050fe518585d3f7f159d26a9",
  42. "control_program": "20b1f38553d95177c53755996baf523da006da977008f069792bb6a2c3b6a253fb160014d470cdd1970b58b32c52ecc9e71d795b02c79a6503e1830403e1830403e256040322350403a21e0403e20e040307fb0320ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4d2b015b7a76529c641d010000640c0100005c7900a0695c790500f2052a01947600a0695379cd9f5579cda09a916164380000005a95639a00000054798ccd9f5679cda09a916164500000005895639a00000055798ccd9f5779cda09a916164680000005695639a00000056798ccd9f5879cda09a916164800000005495639a00000057798ccd9f5979cda09a916164980000005295639a0000005195c3787ca169c3787c9f916164f5000000005e795479515e79c1695178c2516079c16952c3527994c251006079895f79895e79895d79895c79895b79895a79895979895879895779895679890274787e008901c07ec1696307010000005e795479515e79c16951c3c2516079c169632b010000587acd9f6900c3c2515c7ac1632b010000755b7aaa5b7a8800c3c2515d7ac1747800c0",
  43. "type": "control_program"
  44. },
  45. {
  46. "account_id": "0U374V0300A02",
  47. "amount": 5500000000,
  48. "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  49. "type": "spend_account"
  50. },
  51. {
  52. "account_id": "0U374V0300A02",
  53. "amount": 20000000,
  54. "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  55. "type": "spend_account"
  56. }
  57. ],
  58. "ttl": 10000
  59. }

一个解锁合约交易要包含action类型有,

spend_account_unspent_output (合约的参数),

spend_account (输入的资产描述),

control_program或者control_address (接收者资产描述),

可以理解成质量守恒

如上面例子

spend_account_unspent_output 的action里面有个output_id =13fbd1e5df196a1488e85e3b5983e51444c49ef3695df789c9473abb636e0f5c,这个资产的小数位为8(这里没有体现),代表我要解锁这个utxo,他的值为 100000000.00000000 就是1亿。

拆分成两个action,一个 50.00000000,一个 99999950.00000000

只有btm = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 需要用来等手续费,所以允许不守恒,最后由旷工挖矿拿到手续费。

总结:那么程序相当于要把合约里面的逻辑整合进去,才能计算好真正的input、output~~我理解是交易确认的时候,解锁合约的程序验证现在的input、ouput是否跟合约一样。

3)测试解锁合约方法,2)里面采坑已经说清楚这个问题了,补充一下就是最好一下子不要写太复杂的合约,从简单来开发调试。一定要注意质量守恒定律,只要懂了这个原理其实非常简单。

4)基于插件钱包开发Dapp前端, 这块具体可以看插件钱包API储蓄分红合约前端源代码,里面说的非常清楚, 涉及到的接口,暂时他们API文档还没有整理出来,来自上一章说的blockcenter的接口

url地址 :testnet: 'http://app.bycoin.io:3020/', mainnet: 'https://api.bycoin.im:8000/'

核心用到的接口有:

根据合约与资产ID查询UTXO接口

/api/v1/btm/q/list-utxos

参数:
  1. {
  2. "filter": { "script":"20b1f38553d95177c53755996baf523da006da977008f069792bb6a2c3b6a253fb160014d470cdd1970b58b32c52ecc9e71d795b02c79a6503e1830403e1830403e256040322350403a21e0403e20e040307fb0320ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4d2b015b7a76529c641d010000640c0100005c7900a0695c790500f2052a01947600a0695379cd9f5579cda09a916164380000005a95639a00000054798ccd9f5679cda09a916164500000005895639a0000798ccd9f5779cda09a916164680000005695639a00000056798ccd9f5879cda09a916164800000005495639a00000057798ccd9f5979cda09a916164980000005295639a0000005195c3787ca169c3787c9f916164f5000000005e795479515e79c1695178c2516079c16952c3527994c251006079895f79895e79895d79895c79895b79895a79895979895879895779895679890274787e008901c07ec1696307010000005e795479515e79c16951c3c2516079c169632b010000587acd9f6900c3c2515c7ac1632b010000755b7aaa5b7a8800c3c2515d7ac1747800c0",
  3. "asset":"80013f81a66cb99977879e31639bb4fe4b12b4c7058585d3f7f159d26a9" ,
  4. "unconfirmed":false
  5. },
  6. "sort": {
  7. "by":"amount",
  8. "order":"desc"
  9. }
  10. }

unconfirmed ,代表是否确认的,这个对后期的并发问题非常有用,第三章我会详细说明。

结果
  1. {
  2. "code": 200,
  3. "msg": "",
  4. "result": {
  5. "_links": {},
  6. "data": [
  7. {
  8. "hash": "16749b694a9f1bc6a7759cf66baefed4c864b65985e7488e8721184ecc4d6965",
  9. "asset": "80013f81a66cb99977879e31639bb4fe4b12b4c7058585d3f7f159d26a9",
  10. "amount": 3000000000
  11. },
  12. {
  13. "hash": "e5f75036b6f662ff705378b55dd29dc1a43acb23d701dd44a068cdab2c43ad0c",
  14. "asset": "80013f81a66cb99977879e31639bb4fe4b12b4c7058585d3f7f159d26a9",
  15. "amount": 15000000000
  16. }
  17. ],
  18. "limit": 10,
  19. "start": 0
  20. }
  21. }

(自己准备参数调用一下,以上是例子而已)

查询用户地址信息与余额接口

/api/v1/btm/account/list-addresses

参数

{"guid":"b414005b-b501-4a0e-8b0f-e1cd762272f4"}

结果

  1. {
  2. "code": 200,
  3. "msg": "",
  4. "result": {
  5. "_links": {},
  6. "data": [{
  7. "guid": "b414005b-b501-4a0e-8b0f-e1cd762272f4",
  8. "address": "bm1qp4t6thlyktt6sh02scs8dqcpnk3ufk9e9pmq9s",
  9. "label": "",
  10. "balances": [{
  11. "asset": "80013f81a66cb99977879e31639bb4fe4b12b4c7050fe518585d3f7f159d26a9",
  12. "balance": "68900000000",
  13. "total_received": "69000000000",
  14. "total_sent": "100000000",
  15. "decimals": 8,
  16. "alias": "",
  17. "in_usd": "0.00",
  18. "in_cny": "0.00",
  19. "in_btc": "0.000000"
  20. }, {
  21. "asset": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  22. "balance": "1329551000",
  23. "total_received": "53790000000",
  24. "total_sent": "52460449000",
  25. "decimals": 8,
  26. "alias": "btm",
  27. "in_usd": "1.45",
  28. "in_cny": "10.10",
  29. "in_btc": "0.000142"
  30. }]
  31. }],
  32. "limit": 10,
  33. "start": 0
  34. }
  35. }

ps:

​ guid是专门插件钱包提供的,是唯一的,这个非常有用,第三章我会详细说。

查询交易信息

/api/v1/btm/account/list-transactions

参数

{"address":"bm1qp4t6thlyktt6sh02scs8dqcpnk3ufk9e9pmq9s","start":0,"limit":100}

结果

  1. {
  2. "code": 200,
  3. "msg": "",
  4. "result": {
  5. "data": [{
  6. "ID": 111,
  7. "Hash": "471e5b267f646546be33505773186ee9d8dde2180a515df67a90d1a5f9d17bd2",
  8. "AssetID": "80013f81a66cb99977879e31639bb4fe4b12b4c7050fe518585d3f7f159d26a9",
  9. "Amount": 7000000000,
  10. "Address": "bm1qp4t6thlyktt6sh02scs8dqcpnk3ufk9e9pmq9s",
  11. "BaseID": 5,
  12. "Timestamp": "2019-07-08T09:23:12+08:00",
  13. "Height": 263728,
  14. "TransactionID": "471e5b267f646546be33505773186ee9d8dde2180a515df67a90d1a5f9d17bd2",
  15. "InputAmount": 5700000000
  16. }, {
  17. "ID": 64,
  18. "Hash": "e69631a8d6321d738793646399ffe022ac177a5732f562970e706ee76d49de82",
  19. "AssetID": "80013f81a66cb99977879e31639bb4fe4b12b4c7050fe518585d3f7f159d26a9",
  20. "Amount": 5000000000,
  21. "Address": "bm1qp4t6thlyktt6sh02scs8dqcpnk3ufk9e9pmq9s",
  22. "BaseID": 5,
  23. "Timestamp": "2019-07-05T16:37:07+08:00",
  24. "Height": 262170,
  25. "TransactionID": "e69631a8d6321d738793646399ffe022ac177a5732f562970e706ee76d49de82",
  26. "InputAmount": 5500000000
  27. }, {
  28. "ID": 56,
  29. "Hash": "cf74906808a1a6bc6a056c148510d542a10d2cbc350a4d830c670aa5ba973873",
  30. "AssetID": "80013f81a66cb99977879e31639bb4fe4b12b4c7050fe518585d3f7f159d26a9",
  31. "Amount": 39000000000,
  32. "Address": "bm1qp4t6thlyktt6sh02scs8dqcpnk3ufk9e9pmq9s",
  33. "BaseID": 5,
  34. "Timestamp": "2019-07-03T14:59:22+08:00",
  35. "Height": 261006,
  36. "TransactionID": "cf74906808a1a6bc6a056c148510d542a10d2cbc350a4d830c670aa5ba973873",
  37. "InputAmount": 8900000000
  38. }, {
  39. "ID": 54,
  40. "Hash": "6aedf609d47b3c06de2ce7dc9f2c99895124c80074573cd29407ac3b34ef8d40",
  41. "AssetID": "80013f81a66cb99977879e31639bb4fe4b12b4c7050fe518585d3f7f159d26a9",
  42. "Amount": 2000000000,
  43. "Address": "bm1qp4t6thlyktt6sh02scs8dqcpnk3ufk9e9pmq9s",
  44. "BaseID": 5,
  45. "Timestamp": "2019-07-03T12:11:12+08:00",
  46. "Height": 260936,
  47. "TransactionID": "6aedf609d47b3c06de2ce7dc9f2c99895124c80074573cd29407ac3b34ef8d40",
  48. "InputAmount": 5200000000
  49. }]
  50. }
  51. }

5)开发后端,相当于bufferserver,第三章详细说明顺便我解析一下bufferserver的源码内容,还有里面踩过的坑。

总结:

这一章内容主要比较繁琐强调是调试合约方面,就是最核心的问题,这里抛出一个问题,就是UTXO问题,调试过程中非常繁琐,本来区块链不是做高并发,但是也存在并发问题,应该如何解决? 有使用过PC钱包的朋友肯定知道,里面PC钱包的UTXO,在交易过程中锁定了,没办法操作下一个,有些很多UTXO还好,如果只有一个,基本上调试跟实用都很麻烦~~~第三章我们基于原有bufferserver基础上根据官方的方案改一下,一定程度解决并发问题,大家期待一下。

参考资料:

比原链DAPP开发流程

储蓄分红合约Demo访问地址

储蓄分红合约后端bufferserver源码

储蓄分红合约前端源代码

储蓄分红合约详细说明

equity

智能合约学习文档

插件钱包API

作者:天才的饭桶

Bytom Dapp 开发笔记(二):开发流程的更多相关文章

  1. Django开发笔记二

    Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.xadmin添加主题.修改标题页脚和收起左侧菜单 # ...

  2. SDL开发笔记(二):音频基础介绍、使用SDL播放音频

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  3. EasyUI 开发笔记(二)

    接上篇 :EasyUI 开发笔记(一)  (http://www.cnblogs.com/yiayi/p/3485258.html) 这期就简单介绍下, easyui 的 list 展示, 在easy ...

  4. Vue-cli开发笔记二----------接口调用、配置全局变量

    我做的一个项目,本身是没用任何框架,纯手写的前端及数据交互,项目已经完结.最近学Vue,于是借用这个项目,改装成vue项目. (一)接口问题:使用axios的调用方法,proxyTable解决开发环境 ...

  5. RBL开发笔记二

     17:13:55 2014-08-25 有以下几个点:  第一 :怎么在预处理阶段能够做到识别某个宏是否给定义了  这里就定义了一个SystemConfig.h 专门做这个事情  当然是需要make ...

  6. openwrt开发笔记二:树莓派刷openwrt

    前言及准备 本笔记适用于第一次给树莓派刷openwrt系统的玩家,对刷机过程及注意事项进行了记录,刷机之后对openwrt进行一些简单配置. 使用openwrt源码制作固件需要花费一点时间. 平台环境 ...

  7. Electron开发笔记—electron-builder打包流程

    该文章说明基于win平台下,mac及linux没有实验 关于electron-builder打包可以有两种方案: 1. 打包成文件夹及绿色免安装: electron-builder --dir(依赖w ...

  8. wp8开发笔记之开发环境的搭建

    开发工具的下载: Windows phone sdk 8.0下载地址: http://www.microsoft.com/ZH-CN/download/details.aspx?id=35471 开发 ...

  9. Delphi For Android 开发笔记 1 - 开发工具介绍

    在开始前,推荐喜欢delphi或者pascal的朋友,如果想将原来Windows的软件工程移植到Android,可使用CodeTyphon+Delphi XE7进行开发. 1.CodeTyphon C ...

  10. nrf开发笔记一开发软件

    nrf52810 的开发环境,比较主流的可以使用keil,iar亦可.sdk中,使用的是pca10040e,s112.虽然开发板共用一个型号(pca10040) keil5中,cmsis 需要4.5. ...

随机推荐

  1. redis(十五):Redis 有序集合(sorted set)(python)

    #coding:utf8 import redis r =redis.Redis(host="23.226.74.190",port=63279,password="66 ...

  2. Jsonp处理跨域请求

    Jsonp的使用需要前端和后端共同配合来完成 服务端设置(ASP.NET MVC实现): 在将返回的Json数据包在一个方法名称的内部,如上 客户端设置: 同时要加上一个回调函数用于处理请求的数据 在 ...

  3. 《串并行数据结构与算法(SML语言)实验》题解

    注意:本题解仅供参考学习,请勿直接抄袭代码,否则造成的后果和笔者无关. 第一题: 题意: 对n个数升序排序. 题解: 快排,不解释. 代码(省略了输入输出函数,下同): val n = getInt ...

  4. bzoj3442学习小组

    bzoj3442学习小组 题意: 共有n个学生,m个学习小组,每个学生只愿意参加其中的一些学习小组,且一个学生最多参加k个学习小组.每个学生参加学习小组财务处都收一定的手续费,不同的学习小组有不同的手 ...

  5. Ethical Hacking - GAINING ACCESS(1)

    Gaining Access Introduction Everything is a computer Two main approaches (1)Server Side Do not requi ...

  6. split().reverse().join()代码解析

    split() 方法用于把一个字符串分割成字符串数组. reverse() 方法用于颠倒数组中元素的顺序. join() 方法用于把数组中的所有元素放入一个字符串.

  7. 17 个 Python 特别实用的操作技巧,记得收藏!

    Python 是一门非常优美的语言,其简洁易用令人不得不感概人生苦短.在本文中,作者 Gautham Santhosh 带我们回顾了 17 个非常有用的 Python 技巧,例如查找.分割和合并列表等 ...

  8. html地图定位

    利用高德地图api实现简单的地图功能,包括定位,地图缩放,搜索,列表展示等等基础功能 <!doctype html> <html> <head> <meta ...

  9. ThinkPHP5.0、5.1和6.0教程文档合集(免费下载)

    我们都知道ThinkPHP是一个免费开源的,快速.简单的面向对象的轻量级PHP开发框架. ThinkPHP6主要更新了什么呢? 1. 支持PHP最新的强类型 2. PSR开发规范得了更广泛的应用 3. ...

  10. finalize()和四种引用的一点思考

    一次对ThreadLocal的学习引发的思考 ThreadLocal对Entry的引用是弱引用,于是联想到四种引用的生命周期. 强引用,不会进行垃圾回收 软引用,JVM内存不够,进行回收 弱引用,下次 ...