标题
最近因项目使用 tron 协议接入区块链, 故对其做了一番研究, 先把相关资料整理一遍, 供大家学习使用;
网上的这部分资料很少, 所以学习起来也是遇到了很多困难, 尤其是里面很多新的概念, 理解起来有一定的难度。比如说去中心化、地址、加密算法、算法因子、私钥含义、助记词、trc 协议、智能合约、usdt 等等;
很多人接触区块链, 大多是通过接触 usdt 这种中充当稳定资产(也称泰达币)角色开始的, usdt 是什么? 下面我们探讨一下这个问题。
USDT 是一种将加密货币与法定货币美元挂钩的虚拟货币 , 一种基本衡量单位的代币; Tether 公司推出的基于稳定价值货币美元(USD)的代币 Tether USD(下称 USDT), 1USDT=1 美元, 用户可以随时使用 USDT 与 USD 进行 1:1 兑换。
公司对外宣称严格遵守 1: 1 的准备金保证, 即每发行 1 个 USDT 代币, 其银行账户都会有 1 美元的资金保障。用户可以在 Tether 平台进行资金查询, 以保障透明度这样然后 usdt 稳定资产发行者通过存入三方银行机构法定资产, 来保证我的 usdt 是有保证的, 不会超发或者失去赔付能力;
我们怎么知道 Tether 公司所说的真实性呢?
这一点我们通过 Tether 官网 (https://tether.to/en/supported-protocols/) 进行查看, 进入透明度 (https://tether.to/en/transparency/) 展示界面, 可以看到其发行了多少枚代币, 以及质押情况。
可以看到, 不光有 USDT, 还有 ESDT、CSDT ; 其实 U 是代表美国, E 代表欧洲, C 代表中国的意思。
TRON 是一个开源同时支持智能合约功能的公共区块链平台, 也叫波场链。其创始人是中国人孙宇晨, 他拍过巴菲特的午餐, 牛。好了, 废话不多说, 介绍一些东西吧。
既然我们很多时候提到了链, 那链到底是什么呢?
其实链可以理解为一个平台, 这个平台能够做一些事情。比如运行智能合约, 发行代币等等。当然构建一个去中心化的链就必须要实现一些机制, 比如构建信任机制, 这是去中心化核心中的核心。说到这里要引入一个概念: 共识。即如何在分布式的不信任环境中搭建一个信任的网络?
在区块链系统中没有像银行一样的中心化机构, 所以在进行传输信息、价值转移时, 共识机制解决并保证每一笔交易在所有记帐节点上的一致性和 正确性问题。区块链的这种新的共识机制使其在不依靠中心化组织的情况下, 依然大规模高效协作完成运转。
工作量证明简单理解就是一份证明, 用来确认节点做过一定量的工作。监测工作的整个过程通常是极为低效的, 而通过对工作的结果进行认证来证明完成了相应的工作量, 则是-种非常高效的方式。比特币在区块的生成过程中使用了 PoW 机制, 要得到合理的随机数求解数学难题需要经过大量尝试计算, 通过查看记录和验证区块链信息的证明, 就能知道是否完成了指定难度系数的工作量。
即把资产存在银行里, 银行会通过你持有数字资产的数量和时间给你分配相应的收益。采用 PoS 机制的加密货币资产, 系统会根据节点的持币数量和时间的乘积(币天数)给节点分配相应的权益。
还有一些其他的共识机制, 这里介绍了两种最为广泛和常见的共识机制。
TRON 是一个由很多计算机组成的分布式网络, 计算机上需要运行可以验证区块和交易数据的软件, 也叫节点。您需要在系统上安装运行一个叫做客户端的软件, 才能运行一个节点。
"节点 "指的是一个正在运行的客户端软件。客户端是 TRON 的一个实现, 它可以验证每个区块的所有交易, 保持网络的安全和数据的准确性。目前 TRON 客户端是由 Java 语言实现, 它遵循 TRON 协议, 实现了 TRON 网络和区块链的功能。
每个人可以下载相关源代码, 并运行节点的客户端, 可以自行验证交易; 也可以理解"节点 "指的是一个正在运行的客户端软件。客户端是 TRON 的一个实现, 它可以验证每个区块的所有交易, 保持网络的安全和数据的准确性。
区块是一个包含了一系列交易的集合, 另外一个区块还包含了前一个区块的哈希值, 这种实现方式将各个区块连接到一起形成链。
为了确保 TRON 网络上的所有节点保持一致的状态并就交易的历史达成一致, 我们将交易打包进区块, 实现了数百个交易同时被提交、确认以及同步到全网。每个新创建的区块都包含其父区块的 hash 值。在任何给定的时间, 网络上的几乎所有节点都对区块的数量和历史状态达成一致。
TRX 是 TRON 网络上最主要的加密货币, 就像是以太坊的链上的代币就是 eth; TRX 是 TRON 区块链上帐户的基本单位, 在 tron 链上进行的交易活动花费以 trx 作为标准衡量。
TRX 可以被铸造、销毁、转移等行为; 有了这些功能, 我们才能理解后面为啥会有 TRC20-USDT 的概念了?
我们知道 TRON 链支持运行智能合约, 而我们熟知的 TRC20, 其实就是一种合约, 这个合约里面实现了一些功能, 比如代币查询、转移、授权等等功能。
TRC-20 是为发行通证资产而制定的一套合约标准, 即遵守这一标准编写的合约都被认为是一个 TRC-20 合约。当各类钱包、交易所在对接 TRC-20 合约的资产时, 从这套合约标准中就可以知道这个合约定义了哪些函数、事件, 从而方便的进行对接。
要明白 trc20 是一种协议, 这个协议是波场 tron 链下面的一种, 还有 trx, trc10, trc721 等等, 而波场链跟 usdt 发行者公司合作, 写了一份智能合约, 该协议实现了几种功能, 如交易、查询、授权、事件监听等等, 我们在地址中转账看到的 trc20-usdt 就是执行了这个交易方法 transfer, 所以能够把一个地址中的 usdt 转移到另一个地址;
//trc20 协议中支持的方法
contract TRC20 {
function totalSupply() constant returns (uint theTotalSupply);
function balanceOf(address _owner) constant returns (uint balance);
function transfer(address _to, uint _value) returns (bool success);
function transferFrom(address _from, address _to, uint _value) returns (bool success);
function approve(address _spender, uint _value) returns (bool success);
function allowance(address _owner, address _spender) constant returns (uint remaining);
event Transfer(address indexed _from, address indexed _to, uint _value);
event Approval(address indexed _owner, address indexed _spender, uint _value);
}
这下会明白了? 为什么出现了 TRC20-USDT 这个词, 其原因就是如此。同理, 在 eth 链上实现一个支持 USDT 交易的智能合约, 那这个链就能通过 ETH 进行转账交易, 比如说 erc20-usdt。
要实现交易, 首先要得有地址, 自己地址, 对方地址, usdt, trx 燃料费; 然后这几个要素经过什么步骤才能达到目的?
先把代码贴出来:
/**
* 发起 trc20 交易 (目标地址, 数量, 合约地址, 私钥)
* 地址 默认为 usdt 合约地址
* @throws Throwable
*/
public String sendTrc20(String toAddress, BigDecimal amount, String privateKey) throws Throwable {
String ownerAddress = TronUtils.getAddressByPrivateKey(privateKey);
JSONObject jsonObject = new JSONObject();
jsonObject.put("contract_address", TronUtils.toHexAddress(USDT_CPNTRACT));
jsonObject.put("function_selector", "transfer(address,uint256)");
List<Type> inputParameters = new ArrayList<>();
inputParameters.add(new Address(TronUtils.toHexAddress(toAddress).substring(2)));
inputParameters.add(new Uint256(amount.multiply(decimal).toBigInteger()));
String parameter = FunctionEncoder.encodeConstructor(inputParameters);
jsonObject.put("parameter", parameter);
jsonObject.put("owner_address", TronUtils.toHexAddress(ownerAddress));
jsonObject.put("call_value", 0);
jsonObject.put("fee_limit", 6000000L);
String trans1 = HttpClientUtils.postJson(tronUrl + "/wallet/triggersmartcontract", jsonObject.toString());
JSONObject result = JSONObject.parseObject(trans1);
System.out.println("trc20 result:" + result.toJSONString());
if (result.containsKey("Error")) {
throw new RuntimeException("result.containsKey(\"Error\")");
}
JSONObject tx = result.getJSONObject("transaction");
//填写备注
tx.getJSONObject("raw_data").put("data", Hex.toHexString("备注信息".getBytes()));
String txid = TronUtils.signAndBroadcast(tronUrl, privateKey, tx);
if (txid != null) {
System.out.println("txid:" + txid);
return txid;
}
return null;
}
创建交易
String ownerAddress = TronUtils.getAddressByPrivateKey(privateKey);
JSONObject jsonObject = new JSONObject();
jsonObject.put("contract_address", TronUtils.toHexAddress(USDT_CPNTRACT));
jsonObject.put("function_selector", "transfer(address,uint256)");
List<Type> inputParameters = new ArrayList<>();
inputParameters.add(new Address(TronUtils.toHexAddress(toAddress).substring(2)));
inputParameters.add(new Uint256(amount.multiply(decimal).toBigInteger()));
String parameter = FunctionEncoder.encodeConstructor(inputParameters);
jsonObject.put("parameter", parameter);
jsonObject.put("owner_address", TronUtils.toHexAddress(ownerAddress));
jsonObject.put("call_value", 0);
jsonObject.put("fee_limit", 6000000L);
String trans1 = HttpClientUtils.postJson(tronUrl + "/wallet/triggersmartcontract", jsonObject.toString());
JSONObject result = JSONObject.parseObject(trans1);
System.out.println("trc20 result:" + result.toJSONString());
if (result.containsKey("Error")) {
throw new RuntimeException("result.containsKey(\"Error\")");
}
JSONObject tx = result.getJSONObject("transaction");
//填写备注
tx.getJSONObject("raw_data").put("data", Hex.toHexString("备注信息".getBytes()));
先通过私钥获取自己的地址, 然后指定合约地址, 即 usdt 在波场的合约地址, 指定合约中的方法; 然后指定对方地址、附上燃料费 trx , 通过调用 /wallet/triggersmartcontract 创建交易; 至此第一步就算完成了;
这里需要说明, trx 燃料费的概念, 也就是支付给区块链节点的矿工费用; 如果没有 trx 交易是不成功的; 很多人疑惑, 为啥用交易所不需要 trx, 那是因为交易所帮你给付了, 用 web3 wallet 转, 必须支付 trx;
public static String signAndBroadcast(String tronUrl,String privateKey,JSONObject transaction)throws Throwable{
if(tronUrl.endsWith("/")){
tronUrl= tronUrl.substring(0,tronUrl.length() - 1);
}
Protocol.Transaction tx = packTransaction(transaction.toJSONString());
byte[] bytes = signTransactionByte(tx.toByteArray(), ByteArray.fromHexString(privateKey));
String signTransation = Hex.toHexString(bytes);
JSONObject jsonObjectGB = new JSONObject();
jsonObjectGB.put("transaction", signTransation);
String url = tronUrl + "/wallet/broadcasthex";
String transationCompelet1 = HttpClientUtils.postJson(url, jsonObjectGB.toString());
JSONObject transationCompelet = JSONObject.parseObject(transationCompelet1);
System.out.println("signAndBroadcast transationCompelet:" + transationCompelet.toJSONString());
if (transationCompelet.getBoolean("result")) {
return transationCompelet.getString("txid");
} else {
logger.error(String.format("签名交易失败: %s",transationCompelet1));
return null;
}
}
/**
* 签名交易
* @param transaction
* @param privateKey
* @return
* @throws InvalidProtocolBufferException
* @throws NoSuchAlgorithmException
*/
public static byte[] signTransactionByte(byte[] transaction, byte[] privateKey) throws InvalidProtocolBufferException, NoSuchAlgorithmException {
ECKey ecKey = ECKey.fromPrivate(privateKey);
Protocol.Transaction transaction1 = Protocol.Transaction.parseFrom(transaction);
byte[] rawdata = transaction1.getRawData().toByteArray();
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(rawdata,0,rawdata.length);
byte[] hash= digest.digest();
byte[] sign = ecKey.sign(hash).toByteArray();
return transaction1.toBuilder().addSignature(ByteString.copyFrom(sign)).build().toByteArray();
}
在已知交易发起者(contract owner)地址的情况下, 通过签名消息逆推公钥(recover), 并将公钥转换为地址, 与发起者地址进行比较。如果地址一致, 即为验证成功。
验证方法需要三个参数:
byte[] bytes = signTransactionByte(tx.toByteArray(), ByteArray.fromHexString(privateKey));
String signTransation = Hex.toHexString(bytes);
广播可理解为发送交易。任何与波场网络的交互行为都被称作为一笔交易。一笔交易可以是 TRX 转账、质押/解锁 TRX、触发智能合约等。
只有消耗资源的交易才会被记录在链上。前面提到了 trx 燃料费, 就是这里的消耗的资源; 当区块链的其他节点确认了你的交易, 并把此笔交易广播给其他人后, 这笔交易就算交易成功, 即同步到其他节点的数据库了;
wrapper.broadcastTransaction(signedTransaction); //return transaction hash if successfully broadcasted, otherwise the error code
String url = tronUrl + "/wallet/broadcasthex";
String transationCompelet1 = HttpClientUtils.postJson(url, jsonObjectGB.toString());
JSONObject transationCompelet = JSONObject.parseObject(transationCompelet1);
以上就是 trc20-usdt 转账的背后逻辑。下面讲讲 wallet 地址以及 wallet 地址的创建和生成;
账户与地址
TRON 采用账户模型, 账户的唯一标识为地址(address), 对账户操作需要私钥签名。帐户由一对加密密钥组成: 公钥和私钥。公钥映射为地址, 私钥用来对交易进行签名。这对密钥不但可以防止交易被篡改和伪造, 而且还可以证明交易确实是由发送方所发送。私钥由 64 个十六进制字符组成。公钥的生成基于私钥, 并使用椭圆曲线数字签名算法(https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm)来生成对应的公钥。基于公钥可以计算出地址。
账户地址格式
TRON 网络账户地址有两种格式, 一种是 Hex 格式, 另一种是 Base58 格式。
Hex 格式: 用公钥 P 作为输入, 计算 SHA3 得到结果 H, 取 H 的最后 20 字节, 在前面填充一个字节 0x41 得到 Hex 格式地址。例如:
418840E6C55B9ADA326D211D818C34A994AECED808
Base58 格式: 对 hex 格式的地址进行 basecheck 计算得到 Base58 格式地址, 所有账户地址的第一个字符均为 T。例如:
TNPeeaaFB7K9cmo4uQpcU32zGK8G1NYqeL
我们经常看的和使用的就是 Base58 格式的地址。
wallet 钱包可以理解为 管理账户中的地址和私钥的工具, 这些工具可以是 app, 或者网站; 我们称这些工具为钱包, 比如我们常用的钱包 imToken、tronLink 等等。在使用 web3 wallet 时, 经常会让我们主动创建或导入住记词、私钥的方式创建 wallet, 这后面的原理又是什么呢?
我们可以理解 wallet 钱包地址是这套算法中公钥, 这个地址是公开的, 别人可以向你进行交易等等; 而经常说的助记词就是把私钥经过可逆算法转换成了 12 个常见的英文字符串, 二者是等价的(这个过程和产生 wallet 地址、私钥算法不一样), 明白加密算法的人都知道, 加密算法一般不具备可逆向性的, 私钥能推导出公钥的, 反之不行。所以务必保护好你的私钥及代表私钥的助记词。
好了, 明白这些东西后, 那我们看代码:
/**
* 离线创建地址
*
* @return
*/
public static Map<String, String> createAddress() {
ECKey eCkey = new ECKey(random);
String privateKey = ByteArray.toHexString(eCkey.getPrivKeyBytes());
byte[] addressBytes = eCkey.getAddress();
String hexAddress = ByteArray.toHexString(addressBytes);
Map<String, String> addressInfo = new HashMap<>(3);
addressInfo.put("address", toViewAddress(hexAddress));
addressInfo.put("hexAddress", hexAddress);
addressInfo.put("privateKey", privateKey);
return addressInfo;
}
在这个过程中, 涉及到了大量的算法相关的知识, 需要说明的是 tron wallet 的加密算法经过多次转换和加密的, 这个过程非常之复杂, 就不展开讲了。
地址查询
如果我们知道了一个 wallet 地址, 我们可以查询其 wallet 的交易情况, 比如 tron 链上的所有协议, 如 trx 交易、trc20-usdt 交易等等;
String specificWalletTransferUrl = urlAddress + blockWalletBean.monitorAddress + "/transactions/trc20";
Map<String, String> paraMap = new HashMap<>();
paraMap.put("limit", "30");
paraMap.put("only_confirmed", "true");
paraMap.put("contract_address", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t");
String content = httpGet(specificWalletTransferUrl, paraMap);
System.out.println("content:" + content);
f (!StringUtils.isEmpty(content)) {
JSONObject jsonObject = JSONObject.parseObject(content);
JSONArray results = jsonObject.getJSONArray("data");
//解析数据, 获取 wallet address 交易详细信息
区块扫描
public BigInteger getNowBlock() {
String url = tronUrl + "/wallet/getnowblock";
String httpRequest = HttpRequest.get(url).execute().body();
JSONObject jsonObject1 = JSONObject.parseObject(httpRequest);
return jsonObject1.getJSONObject("block_header").getJSONObject("raw_data").getBigInteger("number");
}
其实这个 wallet 、智能合约还有很多的功能, 我们经常听到有些人的被盗, 那些被盗的人怎么做到的呢, 我们该如何去防范呢? 这些东西需要我们深入研究才能明白其中的奥秘, 好了篇幅有限, 至此结束。
目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非
?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
我刚刚看到whitehouse.gov正在使用drupal作为CMS和门户技术。drupal的优点之一似乎是很容易添加插件,而且编程最少,即重新发明轮子最少。这实际上正是Ruby-on-Rails的DRY理念。所以:drupal的缺点是什么?Rails或其他基于Ruby的技术有哪些不符合whitehouse.org(或其他CMS门户)门户技术的资格? 最佳答案 Whatarethedrawbacksofdrupal?对于Ruby和Rails,这确实是一个相当主观的问题。Drupal是一个可靠的内容管理选项,非常适合面向社区的站点。它
文章目录1.任务背景2.任务目标3.相关知识点4.任务实操4.1安装配置JDK4.2启动FISCOBCOS4.3下载解压WeBASE-Front4.4拷贝sdk证书文件4.5启动节点4.6访问节点4.7检查运行状态5.任务总结1.任务背景FISCOBCOS其实是有控制台管理工具,用来对区块链系统进行各种管理操作。但是对于初学者来说,还是可视化界面更友好,本节就来介绍WeBASE管理平台,这是一款微众银行开源的自研区块链中间件平台,可以降低区块链使用的门槛,大幅提高区块链应用的开发效率。微众银行是腾讯牵头设立的民营银行,在国内民营银行里还是比较出名的。微众银行参与FISCOBCOS生态建设,一定
当音乐碰上区块链技术,会擦出怎样的火花?或许周杰伦已经给了我们答案。8月29日下午,B站独家首发周杰伦限定珍藏Demo独家访谈VCR,周杰伦在VCR里分享了《晴天》《青花瓷》《搁浅》《爱在西元前》四首经典歌曲Demo背后的创作故事,并首次公布18年前未发布的神秘作品《纽约地铁》的Demo。在VCR中,方文山和杰威尔音乐提及到“多亏了区块链技术,现在我们可以将这些Demos,变成独一无二具有收藏价值的艺术品,这些Demos可以在薄盒(国内数藏平台)上听到。”如何将音乐与区块链技术相结合,薄盒方面称:“薄盒作为区块链技术服务方,打破传统对于区块链技术只能作为数字收藏的理解。聚焦于区块链技术赋能,在
我感到有点困惑——大约24小时以来,我一直在考虑在我的项目中使用哪种组播技术。基本上,我需要的是:创建组(通过一些后端进程)任意客户端广播消息(1:N,N:N)(可能)直接消息(1:1)(重要)使用我自己的后端(例如,通过某种HTTPAPI)对客户端进行身份验证/授权能够通过后端进程(或服务器插件)踢出特定的客户端这是我要的:Ruby或Haxe中的后端相关流程JS+Haxe(Flash9)中的前端—在浏览器中,因此理想情况下通过80/443进行通信,但不一定。因此,这项技术必须能够在HaxeforFlash中轻松访问,最好是Ruby。我一直在考虑:RabbitMQ(或OpenAMQ)、
文章目录概述背景为何要存算分离优势**应用场景**存算分离产品技术流派华为JuiceFSHashDataXSKY概述背景Hadoop一出生就是奔存算一体设计,当时设计思想就是存储不动而计算(code也即是代码程序)动,负责调度Yarn会把计算任务尽量发到要处理数据所在的实例上,这也是与传统集中式存储最大的不同。为何当时Hadoop设计存算一体的耦合?要知道2006年服务器带宽只有100Mb/s~1Gb/s,但是HDD也即是磁盘吞吐量有50MB/s,这样带宽远远不够传输数据,网络瓶颈尤为明显,无奈之举只好把计算任务发到数据所在的位置。众观历史常言道天下分久必合合久必分,随着云计算技术的发展,数据
文章目录华为OD面试流程1.mysql数据库建了两个字段,且设置了联合索引,如果其中有一个字段为空会出现什么问题?2.谈谈springIOC的理解,有什么好处,解决了什么问题3.谈谈springAOP的理解,切面编程有没有实际应用,有哪些注解,作用是什么,有那些应用场景?4.Erika和zookeeper有了解过吗,作用是什么,主要解决了什么问题5.谈谈JDK、JRE、JVM的理解,区别是什么6.谈谈对泛型的理解7.JVM的组成华为OD面试流程机试:三道算法题,关于机试,橡皮擦已经准备好了各语言专栏,可以直接订阅。性格测试:机试技术一面(本专栏核心)技术二面(本专栏核心)主管面试定级定薪发of
解开谜团:深入探索ChatGPT的技术奇迹。ChatGpt无处不在,无论是在播客、博客、YouTube还是社交媒体上。当我注意到这项新技术如此受欢迎时,我决定试一试,我被震惊了!有很多关于ChatGpt及其魔力的博客,但在这篇博客中,我将深入探讨其内部技术及其工作原理!ChatGpt简介根据OpenAI,ChatGpt被描述为:“我们训练了一个名为ChatGpt的模型,它以对话方式进行交互。对话格式使ChatGpt可以回答后续问题、承认错误、挑战不正确的前提并拒绝不适当的请求。ChatGPT是InstructGPT的兄弟模型,它经过训练可以按照提示中的说明进行操作并提供详细的响应。”OpenA