2019独角兽企业重金招聘Python工程师标准>>>

0x00 前言

基于NEO进行dapp开发的过程中,基于UTXO的GAS并不方便作为dapp的代币使用,于是为了便于在DAPP中直接接入GAS,NEL颜值和技术担当李总开发了基于NEP5的SGAS合约,用于与GAS进行一比一兑换,搭建了应用合约与UTXO之间的桥梁。

尽管SGAS开发的初衷是为了NNS域名竞拍系统的功能实现,但是李总在设计的时候便将SGAS定义为一种通用的NEP5合约,因此任何需要在DAPP中使用GAS作为燃料的合约都可以直接使用SGAS。

0x01 获取SGAS

SGAS是NEP5的代币合约,本身并没有发行量,只有当用户向SGAS合约地址转入GAS时,SGAS合约才会发行对应数量的SGAS代币,并把新发行的SGAS转给该用户。

接下来的内容设计应用合约脚本的构建,建议阅读之前先了解下这方面的知识。

前文已经提到获取SGAS需要用户向SGAS合约地址充值指定金额的GAS,但是仅仅转账是没有办法实现SGAS发行的,因为GAS转账的过程是鉴权合约调用的过程,这个过程中SGAS合约无法进行数据的写入,而SGAS发行代币的方式就是通过数据的记录,这也就意味着SGAS没有办法进行发行操作。为了解决这个问题,在转账之后,还需要通过应用合约的调用过程来向用户地址解锁指定数量的SGAS,完成GAS兑换SGAS的过程。

 var sb = new ThinNeo.ScriptBuilder();sb.EmitParamJson([]);sb.EmitPushString('mintTokens');sb.EmitAppCall(DAPP_SGAS);return sb.ToArray();

在构造交易的时候,传入构造的脚本,这样交易在完成了转账之后会直接执行交易内的脚本。兑换SGAS的指令是 mintTokens ,SGAS合约在接收到这个指令后,会通过runtime获取交易中GAS的output,在对output进行验证和统计后,向该用户的账户解锁对应数量的SGAS。

合约交易构造过程如下:

    let tran = Transfer.makeTran(target, asset, count);tran.type = ThinNeo.TransactionType.InvocationTransaction;tran.extdata = new ThinNeo.InvokeTransData();//塞入脚本(tran.extdata as ThinNeo.InvokeTransData).script = script;return await Transfer.signAndSend(tran);

target是SGAS合约地址,makeTran是合约交易中向交易中添加input和output的标准过程。 因为通过GAS兑换SGAS大部分还是UTXO的操作,所以合约构造和操作起来并不是很复杂,但是当通过SGAS兑换GAS的时候,由于NEP5的诸多限制,操作起来就复杂多了。

0x02 兑换GAS

通过SGAS兑换GAS这个过程,如果真正理解了每一步的原理和原因,对于NEO合约的理解应该算是绝对的一大进步,我这么理解。我第一次看的时候懵懵懂懂,代码量也不大,自己为就看懂了,还跑了测试。但是当我用TS自己去写这块的调用代码的时候,才发现举步维艰,其操作之复杂,设计之精巧远超我想象。这也是为什么我想把SGAS的调用单独写成一篇博客来介绍的原因。

首先我们需要明确几件事:

  1. 兑换GAS用的GAS来自SGAS合约账户本身的GAS。
  2. 每个UTXO只能使用一次。
  3. 转账是鉴权合约操作,而鉴权操作只能读取存储区,不能写存储区。
  4. 应用合约无法发起UTXO交易。

以上四条是无法违背的,在兑换GAS的过程中,必须遵循。那现在就需要思考以下几个问题:

  1. SGAS合约如何转账GAS?
  2. SGAS如何控制转账金额?
  3. 如何转GAS给指定账户?

首先我们分析第一个问题,SGAS合约如何转GAS。为了账户的安全,NEO合约无法进行主动的UTXO转账,必须由用户进行鉴权调用,执行转账操作。也就是说,SGAS无法主动退回GAS给用户,必须由用户来从SGAS账户转出GAS。

第二个问题如何控制转账金额。有NEO账户并且进行过NEO或者GAS转账的童鞋应该知道,只要你有转账权限,那么转账的金额完全是由你自己指定的,也就是说,只要你愿意,那你完全可以转出一个账户里的所有资产。但是对于SGAS合约来说,这样就不行,一旦给了用户转账的权限,我们完全无法依靠上帝保佑所有用户只会转出他希望兑换的金额的GAS。

也就是说我们现在我们必须给用户转账的权限,但是又需要限制用户转账的金额。这怎么办?

同时,由于GAS本身是艺UTXO的形式存在,而UTXO本身又是无法分割,一次使用的,我们无法保证对于每一个用户希望兑换的GAS额度都刚好有对应金额的GAS的UTXO存在,那我们如何分割UTXO来构造出用户需要的UTXO呢?

当然,这些问题都是我在看到李总的解决方案之后,又通过几乎一行代码一行代码向印炜大神请教之后才整理出的。

接下来就开始分析李总对于这一系列几乎使得SGAS方案陷于不可行问题的解决方案。

第一步: 获取可用UTXO。

由于转账操作无论如何都需要用户主动发起,所以用户必须首先获取SGAS合约地址的GAS的UTXO。

第二步:查询UTXO可用性。

多出这一步的原因是由于兑换GAS操作的复杂性,在一个共识周期内无法完成所有操作,所以本轮共识很可能会有之前共识周期中已经被标记的UTXO存在,我们需要在使用之前检测以下这个UTXO是否被标记过。

   var sb = new ThinNeo.ScriptBuilder();sb.EmitParamJson([output_hash]);sb.EmitPushString('getRefundTarget');sb.EmitAppCall(DAPP_SGAS);return sb.ToArray();

第三步:拆分UTXO。

由于UTXO只能使用一次,每次被使用过后就会报废,因此我们只能通过构造才能获得我们需要数额的UTXO,通过SGAS合约给SGAS合约自己的地址转账构造出用户需要的UTXO。同时用户需要记录下这个UTXO。

该步骤主体就是普通的转账操作,直接构造ContractTransaction就可以,需要注意的地方是,这里用的input和指向的output地址都需要是SGAS合约地址。此外,在添加见证人的时候,除了需要添加用户签名之外,还需要添加sgas合约脚本为见证脚本。

  let sb = new ThinNeo.ScriptBuilder();sb.EmitPushString("whatever")sb.EmitPushNumber(newNeo.BigInteger(250));tran.AddWitnessScript(SGASScript,sb.ToArray());

第四步:标记UTXO。

由于转账GAS是个鉴权操作,所以我们还需要在转账之后进行一个合约调用来标记用户生成的对应UTXO,将这个UTXO标记为只能该用户领取。

标记UTXO本身是GSAS合约的工作,但是这部分功能还需要用户进行触发才能执行,在用户拆分UTXO的时候,需要构造一个脚本来进行SGAS合约的调用:

  var sb = new ThinNeo.ScriptBuilder();sb.EmitParamJson([address_hash]);sb.EmitPushString('refund');sb.EmitAppCall(DAPP_SGAS);return sb.ToArray();

第五步:领取GAS。

用户在经过一个共识周期确认UTXO已经拆分完成并且标记完成之后就可以通过记录的UTXO来进行SGAS转账,由于在SGAS应用合约执行期间用户地址就已经和该UTXO进行了绑定因此,在转账的时候,只有该用户可以转走这个UTXO。

至此,SGAS兑换GAS完成。

光是看描述原理的篇幅都知道这个SGAS兑换GAS是多么复杂的一个过程,当然这也是因为目前NEO的一些限制导致的,如果未来NEO对DAPP开放更多的接口和权限,这个过程肯定会大大简化。

不知道看到这里的人有没有对李总的清奇脑洞震撼到,这鉴权调用和应用调用翻来倒去,对此稍有一点不清楚都会云里雾里不知所云。尤其是当所有的代码都写在同一个文件里的时候,感觉都是两种人格在战斗。

参考资料:

SGAS:https://github.com/NewEconoLab/neo-ns/blob/master/dapp_sgas/sgas.cs

ThinSDK-cs:https://github.com/NewEconoLab/neo-thinsdk-cs/blob/master/smartContractDemo/tests/nns/sgas.cs

nel-wallet-vue: https://github.com/NewEconoLab/nel-wallet-vue

转载于:https://my.oschina.net/u/2276921/blog/1843182

NNS域名系统之SGAS相关推荐

  1. 全面讲解Web3.0域名的应用场景-赛道情况-未来挑战

    第一章,Web3域名介绍:用户的"Web3昵称",链上地址的封装 第二章,Web3域名的应用场景:在应用中统一账户名和身份数据,和Web2网页地址互联互通,自身作为身份管理和社交展 ...

  2. 你的Web3域名 价值究竟何在?

    当你又一次听说某 Web3 域名被卖出天价的时候,当你又一次看到身边一位 Web3 朋友改用域名作为其用户名的时候,当你开始在注册栏中物色自己感兴趣的域名的时候,你是否有深思,这些域名究竟有么用?不同 ...

  3. 你的Web3域名,价值究竟何在?

    当你又一次听说某Web3域名被卖出天价的时候,当你又一次看到身边一位Web3朋友改用域名作为其用户名的时候,当你开始在注册栏中物色自己感兴趣的域名的时候,你是否有深思,这些域名究竟有么用?不同项目之前 ...

  4. 域名管理系统 二级域名_域名系统简介

    域名管理系统 二级域名 by Sumedh Nimkarde 由Sumedh Nimkarde 域名系统简介 (An introduction to the Domain Name System) Y ...

  5. dns (域名系统)

    dns (域名系统) DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP ...

  6. 对我国域名系统安全问题的思考

    以互联网为基础的信息网络是进行国家信息化建设和实现国家信息化战略的基础设施,域名系统是互联网上大部分服务和应用正常运转和实施的基石,是互联网上最为关键的基础网络服务之一,事关互联网乃至国家的稳定和安全 ...

  7. 中国发布自主开发的域名系统基础软件 “红枫”

    百度智能云 云生态狂欢季 热门云产品1折起>>>   9月12日消息,域名工程中心(英文缩写 ZDNS)发布了宣称自主开发的域名系统基础软件 "红枫(Maple DNS)& ...

  8. 域名系统DNS、文件传送协议FTP、动态主机配置协议DHCP、远程登录协议TELNET、电子邮件协议(SMTP/POP3/IMAP)、常用端口

    1.DNS域名系统 Domain Name System DNS 是一个分布式数据库,提供了主机名和 IP 地址之间相互转换的服务. 这里的分布式数据库是指,每个站点只保留它自己的那部分数据. 域名具 ...

  9. DNS(域名系统)体系介绍

    一.DNS服务器的功能 DNS作用:在IP地址和主机名之间建立连接,通俗的说就是给互联网上的主机取名字. DNS即域名系统本质上是由各种各样的服务器来完成相关功能的,这些服务器成为DNS服务器,DNS ...

最新文章

  1. 深刻理解Vue中的组件
  2. 【Pygame小游戏】剧情流推荐:什么样的游戏才能获得大家的喜欢呢?(魔鬼恋人、霸总娇妻版)
  3. Ubantu使用笔记
  4. 巨鲸任务调度平台:spark flink任务调度
  5. NgRx Store createSelector 的单步调试和源代码分析
  6. html5能火多久,html5有多火?看完这个你就知道了!
  7. XML入门经典(第五版)
  8. enterFrame是什么意思?
  9. linux 命令tf,linux——新手提问(关于文件内容替换)
  10. vue学习笔记(五):对于vuex的理解 + 简单实例
  11. web电商、商城pc端、商城、购物车、订单、线上支付、web商城、pc商城、登录注册、人工客服、收货地址、现金券、优惠券、礼品卡、团购订单、评价晒单、消息通知、电子产品商城、手机商城、电脑商城
  12. 掌门教育微服务体系 Solar(下)
  13. 《Arduino奇妙之旅:智能车趣味制作天龙八步》一1.4 轰!
  14. 题解 P2212 【[USACO14MAR]浇地Watering the Fields】
  15. 在哪里看服务器cpu占用率,top命令查看服务器cpu使用情况等
  16. java cxf encoded,java:JAXWS 2.0不支持Rpc / encoded wsdls
  17. 无限流量服务器可靠吗,你的无限流量真纯正吗?别再被骗了!
  18. xlwings库的基本使用笔记
  19. vscode vuejs项目import报错找不到模块“@/assets/image/BackGroun.png”或其相应的类型声明。
  20. 毕业论文关键字HTML5,毕业论文关键词的选择

热门文章

  1. innodb--聚簇索引真实案列排序问题
  2. 使用Delphi编写棋牌类游戏 – 设计篇(3)
  3. 详细分析Apple macOS 6LowPAN 漏洞(CVE-2020-9967)
  4. 初创企业如何实现2天快速上线?
  5. Spring Cloud连载(2)搭建开发环境
  6. linux系统下文件查找
  7. System.getProperty的用法
  8. python获取Linux信息
  9. 酷盘API C# 测试版
  10. 学以致用 知行合一 ——《产品管理与研发项目管理》课程有感