开发者-文档

开发者-文档-代码示例

1. 服务连接

//创建服务代理
public static BlockchainKeyPair CLIENT_CERT = BlockchainKeyGenerator.getInstance().generate();
final String GATEWAY_IP = "127.0.0.1";
final int GATEWAY_PORT = 80;
final boolean SECURE = false;
GatewayServiceFactory serviceFactory = GatewayServiceFactory.connect(GATEWAY_IP, GATEWAY_PORT, SECURE,
        CLIENT_CERT);
// 创建服务代理;
BlockchainService service = serviceFactory.getBlockchainService();


2. 用户注册

// 创建服务代理;
BlockchainService service = serviceFactory.getBlockchainService();
// 在本地定义注册账号的 TX;
TransactionTemplate txTemp = service.newTransaction(ledgerHash);
SignatureFunction signatureFunction = asymmetricCryptography.getSignatureFunction(CryptoAlgorithm.ED25519);
CryptoKeyPair cryptoKeyPair = signatureFunction.generateKeyPair();
BlockchainKeyPair user = new BlockchainKeyPair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey());

txTemp.users().register(user.getIdentity());

// TX 准备就绪;
PreparedTransaction prepTx = txTemp.prepare();
// 使用私钥进行签名;
CryptoKeyPair keyPair = getSponsorKey();
prepTx.sign(keyPair);

// 提交交易;
prepTx.commit();


3. 数据账户注册

// 创建服务代理; BlockchainService service = serviceFactory.getBlockchainService(); // 在本地定义注册账号的 TX; TransactionTemplate txTemp = service.newTransaction(ledgerHash); SignatureFunction signatureFunction = asymmetricCryptography.getSignatureFunction(CryptoAlgorithm.ED25519); CryptoKeyPair cryptoKeyPair = signatureFunction.generateKeyPair(); BlockchainKeyPair dataAccount = new BlockchainKeyPair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey());

txTemp.dataAccounts().register(dataAccount.getIdentity());

// TX 准备就绪;
PreparedTransaction prepTx = txTemp.prepare();
// 使用私钥进行签名;
CryptoKeyPair keyPair = getSponsorKey();
prepTx.sign(keyPair);

// 提交交易;
prepTx.commit();


4. 写入数据

// 创建服务代理; BlockchainService service = serviceFactory.getBlockchainService();

HashDigest ledgerHash = getLedgerHash();
// 在本地定义注册账号的 TX;
TransactionTemplate txTemp = service.newTransaction(ledgerHash);

// --------------------------------------
// 将商品信息写入到指定的账户中;
// 对象将被序列化为 JSON 形式存储,并基于 JSON 结构建立查询索引;
String commodityDataAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf==";
Commodity commodity1 = new Commodity();
txTemp.dataAccount(commodityDataAccount).set("ASSET_CODE", commodity1.getCode().getBytes(), -1);

// TX 准备就绪;
PreparedTransaction prepTx = txTemp.prepare();

String txHash = ByteArray.toBase64(prepTx.getHash().toBytes());
// 使用私钥进行签名;
CryptoKeyPair keyPair = getSponsorKey();
prepTx.sign(keyPair);

// 提交交易;
prepTx.commit();


5. 查询数据

// 创建服务代理; BlockchainService service = serviceFactory.getBlockchainService();

// 查询区块信息;
// 区块高度;
long ledgerNumber = service.getLedger(LEDGER_HASH).getLatestBlockHeight();
// 最新区块;
LedgerBlock latestBlock = service.getBlock(LEDGER_HASH, ledgerNumber);
// 区块中的交易的数量;
long txCount = service.getTransactionCount(LEDGER_HASH, latestBlock.getHash());
// 获取交易列表;
LedgerTransaction[] txList = service.getTransactions(LEDGER_HASH, ledgerNumber, 0, 100);
// 遍历交易列表
for (LedgerTransaction ledgerTransaction : txList) {
        TransactionContent txContent = ledgerTransaction.getTransactionContent();
        Operation[] operations = txContent.getOperations();
        if (operations != null && operations.length > 0) {
                for (Operation operation : operations) {
                        operation = ClientOperationUtil.read(operation);
                        // 操作类型:数据账户注册操作
                        if (operation instanceof  DataAccountRegisterOperation) {
                                DataAccountRegisterOperation daro = (DataAccountRegisterOperation) operation;
                                BlockchainIdentity blockchainIdentity = daro.getAccountID();
                        }
                        // 操作类型:用户注册操作
                        else if (operation instanceof UserRegisterOperation) {
                                UserRegisterOperation uro = (UserRegisterOperation) operation;
                                BlockchainIdentity blockchainIdentity = uro.getUserID();
                        }
                        // 操作类型:账本注册操作
                        else if (operation instanceof LedgerInitOperation) {

                                LedgerInitOperation ledgerInitOperation = (LedgerInitOperation)operation;
                                LedgerInitSetting ledgerInitSetting = ledgerInitOperation.getInitSetting();

                                ParticipantNode[] participantNodes = ledgerInitSetting.getConsensusParticipants();
                        }
                        // 操作类型:合约发布操作
                        else if (operation instanceof ContractCodeDeployOperation) {
                                ContractCodeDeployOperation ccdo = (ContractCodeDeployOperation) operation;
                                BlockchainIdentity blockchainIdentity = ccdo.getContractID();
                        }
                        // 操作类型:合约执行操作
                        else if (operation instanceof ContractEventSendOperation) {
                                ContractEventSendOperation ceso = (ContractEventSendOperation) operation;
                        }
                        // 操作类型:KV存储操作
                        else if (operation instanceof DataAccountKVSetOperation) {
                                DataAccountKVSetOperation.KVWriteEntry[] kvWriteEntries =
                                                ((DataAccountKVSetOperation) operation).getWriteSet();
                                if (kvWriteEntries != null && kvWriteEntries.length > 0) {
                                        for (DataAccountKVSetOperation.KVWriteEntry kvWriteEntry : kvWriteEntries) {
                                                BytesValue bytesValue = kvWriteEntry.getValue();
                                                DataType dataType = bytesValue.getType();
                                                Object showVal = ClientOperationUtil.readValueByBytesValue(bytesValue);
                                                System.out.println("writeSet.key=" + kvWriteEntry.getKey());
                                                System.out.println("writeSet.value=" + showVal);
                                                System.out.println("writeSet.type=" + dataType);
                                                System.out.println("writeSet.version=" + kvWriteEntry.getExpectedVersion());
                                        }
                                }
                        }
                }
        }
}

// 根据交易的 hash 获得交易;注:客户端生成 PrepareTransaction 时得到交易hash;
HashDigest txHash = txList[0].getTransactionContent().getHash();
Transaction tx = service.getTransactionByContentHash(LEDGER_HASH, txHash);
// 获取数据;
String commerceAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf==";
String[] objKeys = new String[] { "x001", "x002" };
KVDataEntry[] kvData = service.getDataEntries(LEDGER_HASH, commerceAccount, objKeys);

long payloadVersion = kvData[0].getVersion();

// 获取数据账户下所有的KV列表
KVDataEntry[] kvData = service.getDataEntries(ledgerHash, commerceAccount, 0, 100);
if (kvData != null && kvData.length > 0) {
        for (KVDataEntry kvDatum : kvData) {
                System.out.println("kvData.key=" + kvDatum.getKey());
                System.out.println("kvData.version=" + kvDatum.getVersion());
                System.out.println("kvData.type=" + kvDatum.getType());
                System.out.println("kvData.value=" + kvDatum.getValue());
        }
}


6. 合约发布

// 创建服务代理;
BlockchainService service = serviceFactory.getBlockchainService();

// 在本地定义TX模板
TransactionTemplate txTemp = service.newTransaction(ledgerHash);

// 合约内容读取
byte[] contractBytes = FileUtils.readBytes(new File(CONTRACT_FILE));

// 生成用户
BlockchainIdentityData blockchainIdentity = new BlockchainIdentityData(getSponsorKey().getPubKey());

// 发布合约
txTemp.contracts().deploy(blockchainIdentity, contractBytes);

// TX 准备就绪;
PreparedTransaction prepTx = txTemp.prepare();

// 使用私钥进行签名;
CryptoKeyPair keyPair = getSponsorKey();

prepTx.sign(keyPair);

// 提交交易;
TransactionResponse transactionResponse = prepTx.commit();

assertTrue(transactionResponse.isSuccess());

// 打印合约地址
System.out.println(blockchainIdentity.getAddress().toBase58());




7. 合约调用

// 创建服务代理; BlockchainService service = serviceFactory.getBlockchainService();

// 在本地定义TX模板
TransactionTemplate txTemp = service.newTransaction(ledgerHash);

// 合约地址
String contractAddressBase58 = "";

// Event
String event = "";

// args(注意参数的格式)
byte[] args = "20##30##abc".getBytes();


// 提交合约执行代码
txTemp.contractEvents().send(contractAddressBase58, event, args);

// TX 准备就绪;
PreparedTransaction prepTx = txTemp.prepare();

// 生成私钥并使用私钥进行签名;
CryptoKeyPair keyPair = getSponsorKey();

prepTx.sign(keyPair);

// 提交交易;
TransactionResponse transactionResponse = prepTx.commit();

assertTrue(transactionResponse.isSuccess());


8. 合约开发

/**
 * 示例:一个“资产管理”智能合约的实现;
 *
 * 注: 1、实现 EventProcessingAwire 接口以便合约实例在运行时可以从上下文获得合约生命周期事件的通知; 2、实现
 * AssetContract 接口定义的合约方法;
 *
 * @author huanghaiquan
 *
 */
public class AssetContractImpl implements EventProcessingAwire, AssetContract {
    // 资产管理账户的地址;
    private static final String ASSET_ADDRESS = "2njZBNbFQcmKd385DxVejwSjy4driRzf9Pk";
    // 保存资产总数的键;
    private static final String KEY_TOTAL = "TOTAL";
    // 合约事件上下文;
    private ContractEventContext eventContext;

    /**
     * ------------------- 定义可以由外部用户通过提交“交易”触发的调用方法 ------------------
     */

    @Override
    public void issue(long amount, String assetHolderAddress) {
        checkAllOwnersAgreementPermission();

        // 新发行的资产数量;
        if (amount < 0) {
            throw new ContractError("The amount is negative!");
        }
        if (amount == 0) {
            return;
        }

        // 校验持有者账户的有效性;
        BlockchainAccount holderAccount = eventContext.getLedger().getAccount(currentLedgerHash(), assetHolderAddress);
        if (holderAccount == null) {
            throw new ContractError("The holder is not exist!");
        }

        // 查询当前值;
        Set<String> keys = new HashSet<>();
        keys.add(KEY_TOTAL);
        keys.add(assetHolderAddress);
        StateMap currStates = eventContext.getLedger().getStates(currentLedgerHash(), ASSET_ADDRESS, keys);

        // 计算资产的发行总数;
        StateEntry currTotal = currStates.get(KEY_TOTAL);
        StateEntry newTotal = currTotal.newLong(currTotal.longValue() + amount);

        // 分配到持有者账户;
        StateEntry holderAmount = currStates.get(assetHolderAddress);
        StateEntry newHodlerAmount = holderAmount.newLong(holderAmount.longValue() + amount);

        // 把数据的更改写入到账本;
        SimpleStateMap newStates = new SimpleStateMap(currStates.getAccount(), currStates.getAccountVersion(),
                currStates.getStateVersion());
        newStates.setValue(newTotal);
        newStates.setValue(newHodlerAmount);

        eventContext.getLedger().updateState(ASSET_ADDRESS).setStates(currStates);
    }

    @Override
    public void transfer(String fromAddress, String toAddress, long amount) {
        if (amount < 0) {
            throw new ContractError("The amount is negative!");
        }
        if (amount == 0) {
            return;
        }

        //校验“转出账户”是否已签名;
        checkSignerPermission(fromAddress);

        // 查询现有的余额;
        Set<String> keys = new HashSet<>();
        keys.add(fromAddress);
        keys.add(toAddress);
        StateMap origBalances = eventContext.getLedger().getStates(currentLedgerHash(), ASSET_ADDRESS, keys);
        StateEntry fromBalance = origBalances.get(fromAddress);
        StateEntry toBalance = origBalances.get(toAddress);

        //检查是否余额不足;
        if ((fromBalance.longValue() - amount) < 0) {
            throw new ContractError("Insufficient balance!");
        }

        // 把数据的更改写入到账本;
        SimpleStateMap newBalances = new SimpleStateMap(origBalances.getAccount(), origBalances.getAccountVersion(),
                origBalances.getStateVersion());
        StateEntry newFromBalance = fromBalance.newLong(fromBalance.longValue() - amount);
        StateEntry newToBalance = toBalance.newLong(toBalance.longValue() + amount);
        newBalances.setValue(newFromBalance);
        newBalances.setValue(newToBalance);

        eventContext.getLedger().updateState(ASSET_ADDRESS).setStates(newBalances);
    }
}
目录