文章目录
- 导读
- ❓什么是区块链
- 区块链的应用
- ⚙️运行原理
- ⭕️波场环境
- 主网
- 测试网
- 代码实现
- 区块扫描
- 离线生成地址
- 账户归集
- 调用智能合约
- 离线签名
- 广播交易
- 获取账户余额
- ⚠️仓库地址
- ✊上正式链
- 结语
导读
前两天老同事找到我诉苦:川哥,前段时间产品不知道抽什么风想搞个USDT充值,说什么要与时俱进,与国际接轨。。。。。我tm都研究了两周了都没搞清楚这玩意到底是干嘛的,网上代码不是不全就是缺jar包的,现在搞得我都想rm -rf /*了。。
好家伙,兄弟别冲动啊。。我心想这都什么年代了,币圈起起伏伏竟然还有人觉得区块链是个多么高大上的东西,而且还只是做个支付就叫与时俱进了?不过竟然是前前前同事找我帮忙了,我还是帮助了他并且整理了一下涉及到的关键知识点并且打包好了相关代码,全文干货,建议收藏~
本章只针对TRX(波场)链的USDT充值
注:波场转账消耗费用较低,是目前代币转账用途中比较流行的链。
⚠️⚠️⚠️ 本章提供的内容仅供学习参考,不建议应用于任何商业用途!
❓什么是区块链
简单赘述一下最基本的概念:
- 什么是区块链?
简单来说就是串联的分布式账本,每个账本记录的都是一笔笔转账信息,这个账本我们称之为区块。
- 分布式是什么意思?
分布式就是可以在世界各地的机器上部署节点,这些机器的基本作用就是记账,打包区块。
- 那么多机器怎么保证安全性呢?
假如部署的节点有1000个,如果你想要给自己的账户加钱,你起码要在同一时间篡改一半以上的机器才能让大家都认为你有这么多钱,这个难度不用我多说吧,几乎不可能同时黑那么多服务器。这也就是共识机制,少数服从多数,要大家都觉得你有这么多钱你才有这么多钱。
- 主链是什么
主链就是创世链,如BTC,ETH,EOS,TRX它们都有自己的主链,大部分小币是没有自己的主链的,这些小币大多是跑在某一个链下的虚拟货币,我们称之为代币,而本章涉及的USDT转账使用的就是TRX链。
- 智能合约是什么
说白了就是跑在区块链上的一串代码,如转账功能就是一个典型的实现。你可能还好奇,刚刚还是账本,现在怎么成代码了,这里说一下,区块链是个抽象的概念,账本在这里只是为了方便大家理解,这里不展开叙述。
- 什么是web3.0
说简单点就是可自主开发的智能合约,使之可以在区块链上运行,任何人都可以在区块链上发布一个自己的智能合约。web3.0的概念不同于任何中心化的平台。不管是淘宝、拼多多、WX、ZFB等等你手机上的任何app,他们都拥有自己的数据库,这个数据库他们有绝对的权利作增删改查,但是web3.0不一样,他同样具备共识机制,也就是说,没有任何人可以拥有篡改数据的权限,这也是为什么大家都在说区块链可以帮助我们解决信任问题。
区块链的应用
恕我直言,时至今日,区块链最实际最落地的应用依旧是区块链金融领域,说简单点,炒B。。。
不管是web3.0/元宇宙/溯源/NFT。。。都没有真正普及到被大众熟知并应用,就像二维码那样。不过也不必心急,时代在进步,很多高校都已经开设了面向教师和学生的相关课程,相信不久后区块链就能真正走入每个人的生活。
这里不做过多讨论,本章就手把手教你通过区块链转账实现一个充值功能。
⚙️运行原理
我们的目的是让我们中心化的系统感知到区块链的转账,那么我们的需求就明了了,我们要知道某个账户向我们自己的账户转了一笔钱就行,我们刚刚说了区块链本身就是一个个账本,只要我们不断的扫描最新的区块中有没有向我们账户中转账的记录就可以了。同时我们要保证扫描过的区块不会被重复扫描,即便发生重复扫描,我们也要保证幂等性,流程图如下:
如何扫描最新的区块?
我们有两种扫描的方式,第一种我们自己成为一个节点,去扫描我们自己部署的节点,不过这种方式对机器性能/网络/磁盘要求都比较高,因为会不断的同步整个区块链数据。所以我们采用第二种方案,官方为我们提供了针对TRX链相关的接口,我们直接通过接口的方式来进行操作。
如何知道是某个用户向我转账?
首先,我们并不知道转账的目标用户向我们转账的地址是什么,我们也不可能让用户告诉我们你的转账地址是什么,这样做对用户来说无形之中提高了成本,主流的方案是,给用户提供一个终身唯一的转账充值地址,只要这个地址发生充值,我就知道是哪个用户,相当于在我们的数据库中维护了uid=address的关系。竟然每个用户都对应一个地址,也就是说我们会有很多个账户来接受不同用户的转账,我们还需要将这些USDT做归集。
⭕️波场环境
主网
- 浏览器: https://tronscan.org
- http API: https://api.trongrid.io
- usdt合约地址: TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t
测试网
Nile测试网,Nile测试网用于测试TRON新特性,代码版本一般会领先于主网。本章代码使用该环境。
- 水龙头: http://nileex.io/join/getJoinPage(可以向账户中转入一部分B,只有测试环境有哟)
- 浏览器: https://nile.tronscan.org
- http API: https://api.nileex.io
- usdt合约地址: TXLAQ63Xg1NAzckPwKHvzw7CSEmLMEqcdj
主网就是线上版本,虽说Nile领先主网版本,但是就本章功能而言在主网完全不受影响。
代码实现
区块扫描
扫描第27485294个区块
curl -X POSThttps://api.nileex.io/wallet/getblockbynum -d '{"num":27485294}'
大家可以自己请求一下,数据过长,就不贴出来了,下面是对其中每个字段的释意,其中我们重点关注transactions
下的数据,这里的就是交易数据
blockID 区块hash
block_header 区块头信息,包含区块号,版本号,见证者等块信息
transactions 交易数据,重点关注这里等数据
transactions.ret.contractRet 交易状态,SUCCESS为成功
transactions.ret.signature 签名
transactions.ret.txID 交易ID
transactions.ret.raw_data.contract 调用的合约
parameter.value.data 注意这里数据
‘41’+(下标 32-72) 这串字符是收款人的地址,我们只需要判断该地址值是否为本平台地址即可
倒数非0是转账数量16进制,转为10进制则是本次转账的数量
parameter.value.owner_address 转账人的地址
parameter.value.contract_address 合约地址,这个地址一定要是usdt的合约地址,一定要优先判断是不是usdt合约
注意:不管是合约地址还是转账地址,均为Hex编码地址,如想与Raw地址互转则使用以下代码
System.out.println(AddressUtil.toViewAddress("41ea51342dabbb928ae1e576bd39eff8aaf070a8c6"));System.out.println(AddressUtil.toHexAddress("TXLAQ63Xg1NAzckPwKHvzw7CSEmLMEqcdj"));
我们根据区块号扫描出了这一个块中所有的转账信息,区块号是+1递增的,我们只需要不停的去扫描有没有最新的区块号,如果有正常的返回信息则表示该区块已被确认完成,我们递增继续扫描即可。
离线生成地址
我们为了知道是哪个用户向我们转账,我们需要给每个用户都提供一个单独的转账地址,也就是说我们生成的地址数=要充值的用户数。
对于区块链来说,一个地址就等于一个账户。官方有为我们提供地址的生成,但是由于安全性,正式链中这个api是关闭的,因此我们只能使用离线的方式来生成地址,代码如下
Map<String, String> address = AddressUtil.createAddress();System.out.println(JSON.toJSONString(address));
结果如下
{"privateKey": "f3f2ee18336d1100b3af4001a7d1e3f20eb927468308cc2b5ef31398b03c6f0d","address": "TXNDJs3YqnvqwxLWJUMEipAAdcavdFVeez","hexAddress": "41eab476ff352d00eb38fb8a85c78c854365faf80b"}
- privateKey 私钥,
千万千万千万不要泄露
,有了这串字符别人可以随意转走这个账户中的$ - address Raw地址,转账地址
- hexAddress Hex地址,转账地址
账户归集
什么是账户归集呢?
现在我们生成了n多个地址,里面的¥是分散的,我肯定不可能到每个账户里都操作一次,因此我们需要将这些¥放到到一个大账户中才能方便使用,怎么操作呢?转账!转账到一个账户里就行了,这个操作我们称之为归集。
调用智能合约
curl --request POST \ --url https://api.nileex.io/wallet/triggersmartcontract \ --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --data '{ "owner_address": "41D1E7A6BC354106CB410E65FF8B181C600FF14292", "contract_address": "41ea51342dabbb928ae1e576bd39eff8aaf070a8c6", "function_selector": "transfer(address,uint256)", "fee_limit": 10000000, "parameter": "000000000000000000000041eab476ff352d00eb38fb8a85c78c854365faf80b00000000000000000000000000000000000000000000000000000000000186a0"}'
owner_address 要转账的地址
contract_address 合约地址
function_selector 转账用的function
fee_limit 可接受消耗最大手续费,手续费是TRX
parameter 要转账的目标对象和转账的数量,拼接代码如下
String addressParam = addZero("41eab476ff352d00eb38fb8a85c78c854365faf80b", 64);String amountParam = addZero(Long.toString(100000, 16), 64);System.out.println(addressParam + amountParam);
离线签名
官方有为我们提供签名的接口,同样因为安全性的原因该接口在主网被关闭,可参考以下代码进行离线签名
JSONObject transaction = TransactionUtil.getTransaction("调用智能合约返回的json数据");System.out.println(transaction.toJSONString());
广播交易
将离线签名的数据广播,这时会真正触发转账动作
curl --request POST \ --url https://api.nileex.io/wallet/broadcasttransaction \ --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --data ' 离线签名后的全量数据,这里不贴出来了'
响应数据中的txid
就是我们本次交易的ID,可以在区块链浏览器中查看该笔转账的区块确认状态
注意:转账是需要消耗TRX作为手续费的,建议归集拥有一定条件再归集,如余额大于多少或者一天归集一次,根据实际业务情况判断。
新生成的地址需要往里面转入少量TRX才可以进行转账
获取账户余额
USDT在TRX链中属于一个代币,假如想知道某个账户的余额我们可以通过接口来查询。
curl --request POST \ --url https://api.nileex.io/wallet/triggersmartcontract \ --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --data '{ "owner_address": "41D1E7A6BC354106CB410E65FF8B181C600FF14292", "contract_address": "41ea51342dabbb928ae1e576bd39eff8aaf070a8c6", "function_selector": "balanceOf(address)", "parameter": "000000000000000000000000eab476ff352d00eb38fb8a85c78c854365faf80b"}'
owner_address 本账户地址
contract_address USDT合约地址
function_selector 余额查询方法
parameter为要获取的目标余额账户的地址,取值如下
String addressParam = addZero(hexAddress.substring(2), 64);
响应数据中constant_result
为16进制余额
注意:USDT和TRX小数位精度均为6,在进行通许时需要进行10^6转换
⚠️仓库地址
以上所有工具类均已上传至github: https://github.com/BlackCores/tron_test
使用参考: Test.java
✊上正式链
上正式链需要进行以下准备
将请求地址改为https://api.trongrid.io
将usdt合约地址改为
TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t
准备API TOKEN
自行申请 https://www.trongrid.io/dashboard
每次请求需要带上header:
TRON-PRO-API-KEY
结语
很多人听到区块链第一反应是,炒B,抱负,这仅仅只是区块链的一个应用,我们更应该去思考它能带来的价值,以及如何能够让区块链真正的造福我们,或许在不久的将来,它能像二维码一样走进我们每一个人的生活。