HTTP 请求举例

// 同步发送请求
YOUChain youChain = YOUChain.build(new HttpService("https://test-node.iyouchain.com"));  // 默认指向 http://localhost:8283/
YOUChainClientVersion youChainClientVersion = youChain.youChainClientVersion().send();
String clientVersion = youChainClientVersion.getYOUChainClientVersion();

// 异步发送请求
YOUChain youChain = YOUChain.build(new HttpService("https://test-node.iyouchain.com"));
YOUChainClientVersion youChainClientVersion = youChain.youChainClientVersion().sendAsync().get();
String clientVersion = youChainClientVersion.getYOUChainClientVersion();

// RxJava Flowable
YOUChain youChain = YOUChain.build(new HttpService("https://test-node.iyouchain.com"));
youChain.youChainClientVersion().flowable().subscribe(x -> {
    String clientVersion2 = x.getYOUChainClientVersion();
});

Websocket 请求举例

WebSocketService webSocketService = new WebSocketService("wss://test-node.iyouchain.com/ws",false);
// 建立连接
webSocketService.connect();

YOUChain youChain = YOUChain.build(webSocketService);

Request<?, YOUGasPrice> request = new Request<>(
    // RPC 方法名
    "you_gasPrice",
    // 方法参数
    Collections.<String>emptyList(),
    // Service
    webSocketService,
    // RPC 请求类型
    YOUGasPrice.class);

// 同步请求
YOUGasPrice gasPrice = webSocketService.send(
    request,
    YOUGasPrice.class);

// 异步请求
CompletableFuture<YOUGasPrice> reply = webSocketService.sendAsync(
    request,
    YOUGasPrice.class);
YOUGasPrice gasPrice = reply.get();

查询客户端版本

YOUChainClientVersion clientVersion = youChain.youChainClientVersion().send();
String version = clientVersion.getYOUChainClientVersion();

计算hash值(Keccak-256)

YOUChainSha3 sha3 = youChain.youChainSha3(data).send();
String hash = sha3.getResult();

查询网络id

NetVersion netVersion = youChain.netVersion().send();
String version = netVersion.getResult();

返回值:1表示主网,2测试网

查询节点是否监听网络

NetListening netListening = youChain.netListening().send();
boolean listening = netListening.isListening();

查询连接本节点的节点数

NetPeerCount netPeerCount = youChain.netPeerCount().send();
BigInteger num = netPeerCount.getQuantity();

查询协议版本

YOUProtocolVersion protocolVersion = youChain.youProtocolVersion().send();
String version = protocolVersion.getProtocolVersion();

查询coinbase地址

YOUCoinbase coinbase = youChain.youCoinbase().send();
String address = coinbase.getAddress();

查询同步状态

YOUSyncing youSyncing = youChain.youSyncing().send();
boolean syncing = youSyncing.isSyncing();

查询挖矿状态

YOUMining youMining = youChain.youMining().send();
boolean mining = youMining.isMining();

查询gas价格

YOUGasPrice youGasPrice = youChain.youGasPrice().send();
BigInteger gasPrice = youGasPrice.getGasPrice();

查询客户端持有的地址列表

YOUAccounts youAccounts = youChain.youAccounts().send();
List<String> accounts = youAccounts.getAccounts();

查询最新区块高度

YOUBlockNumber youBlockNumber = youChain.youBlockNumber().send();
BigInteger blockNumber = youBlockNumber.getBlockNumber();

查询地址的余额

YOUGetBalance getBalance = youChain.youGetBalance(address, DefaultBlockParameterName.PENDING).send();
BigInteger balance = getBalance.getBalance();

查询指定地址存储的值

YOUGetStorageAt getStorageAt = youChain.youGetStorageAt(address, BigInteger.ZERO, DefaultBlockParameterName.PENDING).send();
String data = getStorageAt.getData();

查询指定地址的交易数量

YOUGetTransactionCount getTransactionCount = youChain.youGetTransactionCount(address, DefaultBlockParameterName.PENDING).send();
BigInteger nonce = getTransactionCount.getTransactionCount();

根据块hash查询指定块的交易数量

YOUGetBlockTransactionCountByHash getBlockTransactionCountByHash = youChain.youGetBlockTransactionCountByHash(blockHash).send();
Integer transCount = getBlockTransactionCountByHash.getTransactionCount();

根据块高度查询指定块的交易数量

BigInteger number = BigInteger.valueOf(20000); 
DefaultBlockParameter parameter = DefaultBlockParameter.valueOf(number);
YOUGetBlockTransactionCountByNumber getBlockTransactionCountByNumber = youChain.youGetBlockTransactionCountByNumber(parameter).send();
Integer transCount = getBlockTransactionCountByNumber.getTransactionCount();

查询合约地址的合约代码

YOUGetCode youGetCode = youChain.youGetCode(ADDRESS, DefaultBlockParameterName.LATEST).send();
String contractCode = youGetCode.getCode();

对Data进行签名

String data = "hello";
String dataHashed = Hash.sha3(data);
YOUSign youSign = youChain.youSign(address, dataHashed).send();
String signature = youSign.getSignature();

发送交易

发送一笔新的交易,如果data中包含代码,则创建一个合约
youSendTransaction(Transaction transaction);
参数类型:

参数 类型 描述
from String 发起交易的账户地址
to String 交易目标地址(当为新建合约时可为空)
gas BigInteger gas数量,默认值90000,未用gas将返还
gasPrice BigInteger gas价格
value BigInteger 交易金额
data String 合约代码或被调用合约方法的签名及参数
nonce BigInteger nonce,可以使用同一个nonce来实现挂起的交易的重写

返回值:交易哈希,如果交易还未生效则返回0值哈希

Transaction类提供一系列的静态方法来创建Transaction,如:

  • Transaction.createContractTransaction
  • Transaction.createFunctionCallTransaction
  • Transaction.createYOUTransaction
  • Transaction.createYOUCallTransaction

注意:发起交易的账户需要先解锁

示例代码如下:

Admin admin = Admin.build(httpService);
// 先进行解锁
admin.personalUnlockAccount(fromAddress, password).send();
...
BigInteger gasPrice = youChain.youGasPrice().send().getGasPrice();
BigInteger gasLimit = Contract.GAS_LIMIT;
BigInteger nonce = youChain.youGetTransactionCount(fromAddress, DefaultBlockParameterName.PENDING).send().getTransactionCount();
Transaction transaction = Transaction.createYOUTransaction(fromAddress, nonce, gasPrice, gasLimit, toAddress, amount);
YOUSendTransaction transactionResponse = admin.youSendTransaction(transaction).send().get();
String transactionHash = transactionResponse.getTransactionHash();

发送已签名交易

发送一笔新的交易数据,该数据是已经过签名的交易数据,如果原交易数据中data中包含代码,则创建一个合约

RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit, contractAddress, encodedFunction);
byte[] signMessage = TransactionEncoder.signMessage(rawTransaction, credential);
String signedTransactionData = Numeric.toHexString(signMessage);
YOUSendTransaction youSendTransaction = youChain.youSendRawTransaction(signedTransactionData).send();
String transactionHash = youSendTransaction.getTransactionHash();

发送交易调用

执行一个新的合约调用,无需在区块链上创建交易,不消耗gas
youCall(Transaction transaction, DefaultBlockParameter defaultBlockParameter)
参数类型:
Transaction transaction 调用对象
DefaultBlockParameter defaultBlockParameter 区块数据

参数 类型 描述
from String 发起交易的账户地址
to String 交易目标地址(当为新建合约时可为空)
gas BigInteger gas数量,可选。该接口不消耗gas,但是某些执行环节需要这个参数
gasPrice BigInteger gas价格
value BigInteger 交易金额
data String 合约代码或被调用合约方法的签名及参数
nonce BigInteger nonce,可以使用同一个nonce来实现挂起的交易的重写

返回值:所执行合约的返回值
示例代码如下:

Function function = new Function("balanceOf",  // function we're calling
        Arrays.asList(new Address(address)),  // Parameters to pass as Solidity Types
        Arrays.asList(new TypeReference<Uint256>() {
        }));
String encodedFunction = FunctionEncoder.encode(function);
Transaction transaction = Transaction.createYOUCallTransaction(address, contractAddress, encodedFunction);
YOUCall youCall = youChain.youCall(transaction, DefaultBlockParameterName.LATEST).send();

估算gas用量

执行并估算一个交易需要的 gas 用量。该次交易不会写入区块链。估算的数值可能比实际用量大的多。 youEstimateGas(Transaction transaction);
参数类型:

参数 类型 描述
from String 发起交易的账户地址
to String 交易目标地址(当为新建合约时可为空)
gas BigInteger gas数量,可选。该接口不消耗gas,但是某些执行环节需要这个参数
gasPrice BigInteger gas价格
value BigInteger 交易金额
data String 合约代码或被调用合约方法的签名及参数

示例代码如下:

Function function = new Function("balanceOf",  // function we're calling
    Arrays.asList(new Address(address)),  // Parameters to pass as Solidity Types
    Arrays.asList(new TypeReference<Uint256>() {
    }));
String encodedFunction = FunctionEncoder.encode(function);
Transaction transaction = Transaction.createYOUCallTransaction(address, contractAddress, encodedFunction);
YOUEstimateGas youEstimateGas = youChain.youEstimateGas(transaction).send();
BigInteger amountUsed = youEstimateGas.getAmountUsed();

根据区块hash查询区块数据

youGetBlockByHash(String blockHash, boolean returnFullTransactionObjects)
参数类型:

参数 类型 描述
blockHash String 区块哈希
returnFullTransactionObjects Boolean 为 true 时返回完整的交易对象,否则仅返回交易哈希

返回值类型:YOUBlock.Block

名称 类型 描述
number String 区块高度
hash String 区块 hash,挂起块为null
parentHash String 父区块 hash,挂起块为 null
logsBloom String 区快日志的 bloom 过滤器,挂起块为 null
transactionsRoot String 区块中的交易树根节点
stateRoot String 区块最终状态树的根节点
receiptsRoot String 区块交易收据树的根节点
miner String 挖矿奖励的接收账户
extraData String 区块额外数据
size String 区本块字节数
gasLimit String 本区块允许的最大gas用量
gasUsed String 本区块中所有交易使用的总gas用量
timestamp String 区块额外数据
extraData String 区块时间戳
gasRewards String 本块中所有交易的总费用
consensus String 共识有关数据
signature String 区块提议者对区块的签名
slashData String 罚款信息
validator String 投票信息
valRoot String 验证者集合树根节点
chtRoot String 权威哈希树根,只在特定块高上出现(主网将会是 i*32768 )
bltRoot String BloomBits 树根,与chtRoot在相同块高出现
certificate String 对 chtRoot 和 bltRoot 的附加投票数据
version String 当前区块共识协议版本
nextVersion String 下一个区块共识协议版本
nextApprovals String 下一轮投票数量
nextSwitchOn String 如果超过投票阈值,在特定 round 切换版本
nextVoteBefore String 下一次投票到特定的轮数

| transactions | List | 交易对象列表 |

返回值类型:TransactionResult

名称 类型 描述
hash String 交易哈希
nonce BigInteger 本次交易之前发送方已经生成的交易数量
blockHash String 区块哈希
blockNumber BigInteger 区块高度
transactionIndex BigInteger 交易所在区块的顺序
from String 发起方地址
to String 接收方地址
value BigInteger 交易数量
gasPrice BigInteger gas价格
gas BigInteger gas数量
input String 输入参数

示例代码:

YOUBlock youBlock = youChain.youGetBlockByHash(blockHash, Boolean.TRUE).send();
List<YOUBlock.TransactionResult> transactions = youBlock.getBlock().getTransactions();
transactions.forEach(transaction -> {
    YOUBlock.TransactionObject transactionObject = (YOUBlock.TransactionObject) transaction;
    log.info("Transaction from:{}", transactionObject.getFrom());
    log.info("Transaction to:{}", transactionObject.getTo());
});

根据区块高度查询区块数据

youGetBlockByNumber(DefaultBlockParameter defaultBlockParameter, boolean returnFullTransactionObjects);
参数类型:

参数 类型 描述
defaultBlockParameter DefaultBlockParameter 区块高度数据
returnFullTransactionObjects Boolean 为 true 时返回完整的交易对象,否则仅返回交易哈希

返回值可以参考上面[根据区块hash查询区块数据]

根据交易hash查询交易数据

youGetTransactionByHash(String transactionHash)
参数:交易hash
返回值类型:YOUTransaction

名称 类型 描述
hash String 交易哈希
nonce BigInteger 本次交易之前发送方已经生成的交易数量
blockHash String 区块哈希
blockNumber BigInteger 区块高度
transactionIndex BigInteger 交易所在区块的顺序
from String 发起方地址
to String 接收方地址
value BigInteger 交易数量
gasPrice BigInteger gas价格
gas BigInteger gas数量
input String 输入参数

根据区块hash和交易在概况的位置查询交易数据

youGetTransactionByBlockHashAndIndex(String blockHash, BigInteger transactionIndex)

根据区块高度和交易在概况的位置查询交易数据

youGetTransactionByBlockNumberAndIndex(DefaultBlockParameter defaultBlockParameter, BigInteger transactionIndex)

根据交易hash查询交易凭证

youGetTransactionReceipt(String transactionHash)
返回值类型:YOUGetTransactionReceipt

名称 类型 描述
transactionHash String 交易hash
transactionIndex BigInteger 交易在块内的索引序号
blockHash String 交易所在块的哈希
blockNumber BigInteger 交易所在块的编号
cumulativeGasUsed BigInteger 交易所在块消耗的 gas 总量
gasUsed BigInteger 该次交易消耗的 gas 用量
contractAddress String 对于合约创建交易,该值为新创建的合约地址,否则为 null
from String 交易发送方地址
to String 交易接收方地址,对于合约创建交易该值为 null
logs List 本次交易生成的日志对象列表
logsBloom String bloom过滤器,轻客户端用来快速提取相关日志

返回值类型:Log

名称 类型 描述
removed Boolean 如果日志已被删除则返回true,如果是有效日志则返回false
logIndex BigInteger log的索引
transactionIndex BigInteger 交易索引
transactionHash String 交易hash
blockHash String 区块hash
blockNumber BigInteger 区块高度
address String 该日志的源地址
data String 包含该日志的一个或多个32字节无索引参数
topics List 0~4个32字节索引日志参数的数据。在solidity中,第一个主题是事件签名,例如 Deposit(address,bytes32,uint256),除非你声明的是匿名事件

创建过滤器

基于给定的选项创建一个过滤器对象,接收状态变化时的通知。要检查状态是否变化
关于特定主题过滤器的说明:主题是顺序相关的。如果一个交易的日志有主题[A, B],那么将被 以下的主题过滤器匹配: [] 任何主题
[A] 先匹配A主题
[null, B] 先匹配其他主题,再匹配B主题
[A, B] 先匹配A主题,再匹配B主题,最后匹配其他主题
[[A, B], [C, D]] "先匹配A主题或B主题,再匹配C主题或D主题,最后匹配其他主题

示例代码:

YOUFilter youFilter = new YOUFilter(
        DefaultBlockParameter.valueOf(BigInteger.valueOf(30000)),
        DefaultBlockParameterName.LATEST,
        address);
cc.youchain.protocol.core.methods.response.YOUFilter youFilterResp = youChain.youNewFilter(youFilter).send();
BigInteger filterId = youFilterResp.getFilterId();
for (;;) {
    YOULog youLog = youChain.youGetFilterLogs(filterId).send();
    logger.info("youlog={}", youLog.getResult().size());
    youLog.getLogs().forEach(youLg -> {
        logger.info("youLg");
    });
    Thread.sleep(2000);
}

创建新区块过滤器

youNewBlockFilter()

cc.youchain.protocol.core.methods.response.YOUFilter youFilter = youChain.youNewBlockFilter().send();
BigInteger filterId = youFilter.getFilterId();

创建新交易过滤器

youNewPendingTransactionFilter()

cc.youchain.protocol.core.methods.response.YOUFilter youFilter = youChain.youNewPendingTransactionFilter().send();
BigInteger filterId = youFilter.getFilterId();

卸载具有指定编号的过滤器

youUninstallFilter(BigInteger filterId)

YOUUninstallFilter youUninstallFilter = youChain.youUninstallFilter(filterId).send();
boolean uninstalled = youUninstallFilter.isUninstalled();

通过过滤器id查询过滤器满足的新数据

轮询指定的过滤器,并返回自上次轮询之后新生成的日志数组。
youGetFilterChanges(BigInteger filterId)
返回值:

  1. 若filterId是newBlockFilter创建的,则返回区块hash
  2. 若filterId是newPendingTransactionFilter创建的,则返回交易hash
  3. 若filterId是newFilter创建的 返回值类型:Log
名称 类型 描述
removed Boolean 如果日志已被删除则返回true,如果是有效日志则返回false
logIndex BigInteger log的索引
transactionIndex BigInteger 交易索引
transactionHash String 交易hash
blockHash String 区块hash
blockNumber BigInteger 区块高度
address String 该日志的源地址
data String 包含该日志的一个或多个32字节无索引参数
topics List 0~4个32字节索引日志参数的数据。在solidity中,第一个主题是事件签名,例如 Deposit(address,bytes32,uint256),除非你声明的是匿名事件

通过过滤器id查询过滤器全部日志

返回指定编号过滤器中的全部日志。
youGetFilterLogs(BigInteger filterId)
返回值参考youGetFilterChanges

通过过滤器查询所有日志

返回指定编号过滤器中的全部日志。
youGetLogs(YOUFilter youFilter)
返回值参考youGetFilterChanges

新块被添加到区块链时的通知

newHeadsNotifications()

新的交易被添加的节点中时的通知

newPendingTransactionsNotifications() 示例代码:

Flowable<PendingTransactionNotification> flowable = youChainWs.newPendingTransactionsNotifications();
flowable.subscribe(notfication -> {
        logger.info("transaction hash={}", notfication.getParams().getResult());
    },
    error -> {
        logger.error("onError");
    });

节点开始同步或结束同步时的通知

syncingStatusNotifications()

日志被加载到新导入的区块时的通知

logsNotifications(List addresses, List topics) 查询特定地址(一般是合约地址)以及特定主题上的日志通知

响应式编程接口

下面为youchain.java提供的响应式编程接口

  • youBlockHashFlowable 区块hash响应
  • youPendingTransactionHashFlowable 交易hash响应
  • youLogFlowable 日志响应
  • transactionFlowable 交易响应
  • pendingTransactionFlowable pending交易响应
  • blockFlowable 区块响应 示例代码:
    Flowable<String> flowable = youChainWs.youPendingTransactionHashFlowable();
    flowable.subscribe(tx -> {
          logger.info("txHash={}", tx);
      },
      error -> {
          logger.error("onError");
      });
    

再现过滤器接口

youchain.java提供以下几种再现过滤器接口,主要用于重现区块和交易

  • replayPastBlocksFlowable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock,
          boolean fullTransactionObjects);
    
  • replayPastBlocksFlowable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock,
          boolean fullTransactionObjects, boolean ascending);
    
  • replayPastBlocksFlowable(DefaultBlockParameter startBlock, boolean fullTransactionObjects,
          Flowable<YOUBlock> onCompleteFlowable);
    
  • replayPastBlocksFlowable(DefaultBlockParameter startBlock, boolean fullTransactionObjects);
  • replayPastTransactionsFlowable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock);
  • replayPastTransactionsFlowable(DefaultBlockParameter startBlock);
  • replayPastAndFutureBlocksFlowable(DefaultBlockParameter startBlock, boolean fullTransactionObjects);
  • replayPastAndFutureTransactionsFlowable(DefaultBlockParameter startBlock);

使用方式请参考过滤器[再现过滤器]

获取交易池中某个账户的交易数量

参数:

名称 类型 描述
address String 需查询的账户地址
YOUGetPoolNonce youGetPoolNonce = youChain.youGetPoolNonce("0xd7bad0135F8c6bE4C77D8Bc9bE60a51F9b9Ec77B").send();
BigInteger poolNonce = youGetPoolNonce.getPoolNonce();
logger.info("poolNonce: ", poolNonce);

获取交易池中某个账户的交易详情

参数:

名称 类型 描述
transactionHash String 需查询的交易哈希

示例代码:

YOUGetPoolTransaction youGetpoolTransaction = youChain.youGetPoolTransaction("transactionHash").send();
Optional<Transaction> poolTransaction = youGetpoolTransaction.getPoolTransaction();
logger.info("poolTransaction: ", poolTransaction.toString());