现在您拥有了一个帐户,您可以通过POCChain网络发送和接收资金。 如果您尚未创建帐户,请阅读“入门指南”的第2步

大多数情况下,您会将钱汇给拥有自己帐户的其他人。 但是,对于此交互式指南,您应该使用与创建第一个帐户时相同的方法建立第二个帐户进行交易。

发送付款

改变POCChain事态的行为,如发送付款,更改帐户或提供交易各种货币的要约,都称为operations 操作。[1]为了实际执行操作,您需要创建一个transaction 交易,该交易只是一组操作,附带一些额外信息,例如进行交易的帐户和用于验证交易是否真实的加密签名。[2]

如果交易中的任何操作失败,则它们都会失败。例如,假设您有100帕克币,并且您进行两次每次60帕克币的付款操作。如果你做两个交易(每个交易都有一个操作),第一个将成功,第二个将失败,因为你没有足够的帕克币。你将留下40帕克币。但是,如果您将两笔付款合并为一笔交易,它们都会失败,您的帐户中仍会留下100美元的帕克币。

最后,每笔交易都需要支付少量费用。与帐户的最低余额一样,此费用有助于阻止人们通过大量交易使系统过载。被称为基本费用,每次操作非常小 - 100 stroops(即0.00001 POCC; stroops比帕克币的这些微小部分更容易谈论)。具有两个操作的交易将花费200个stroops。[3]

建立交易

POCChain以二进制格式存储和传递交易数据,称为XDR。[4] 幸运的是,Stellar SDK提供了处理所有这些的工具。 以下是您可以将10帕克币发送到另一个帐户的方法:

Network.useTestNetwork();
Server server = new Server("https://horizon-testnet.stellar.org");

KeyPair source = KeyPair.fromSecretSeed("SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4");
KeyPair destination = KeyPair.fromAccountId("GA2C5RFPE6GCKMY3US5PAB6UZLKIGSPIUKSLRB6Q723BM2OARMDUYEJ5");

// First, check to make sure that the destination account exists.
// You could skip this, but if the account does not exist, you will be charged
// the transaction fee when the transaction fails.
// It will throw HttpResponseException if account does not exist or there was another error.
server.accounts().account(destination);

// If there was no error, load up-to-date information on your account.
AccountResponse sourceAccount = server.accounts().account(source);

// Start building the transaction.
Transaction transaction = new Transaction.Builder(sourceAccount)
        .addOperation(new PaymentOperation.Builder(destination, new AssetTypeNative(), "10").build())
        // A memo allows you to add your own metadata to a transaction. It's
        // optional and does not affect how Stellar treats the transaction.
        .addMemo(Memo.text("Test Transaction"))
        .build();
// Sign the transaction to prove you are actually the person sending it.
transaction.sign(source);

// And finally, send it off to Stellar!
try {
  SubmitTransactionResponse response = server.submitTransaction(transaction);
  System.out.println("Success!");
  System.out.println(response);
} catch (Exception e) {
  System.out.println("Something went wrong!");
  System.out.println(e.getMessage());
  // If the result is unknown (no response body, timeout etc.) we simply resubmit
  // already built transaction:
  // SubmitTransactionResponse response = server.submitTransaction(transaction);
}

究竟发生了什么? 让我们分解吧。

  1. 通过从POCChain网络加载关联的帐户数据,确认您要发送到的帐户ID实际存在。 如果你跳过这一步,一切都会好起来的,但是这样做可以让你有机会避免做出你知道会失败的交易。 您还可以使用此调用执行您可能要在目标帐户上执行的任何其他验证。 例如,如果您正在编写银行软件,这是插入监管合规性检查和KYC验证的好地方。
    server.accounts().account(destination);
    
  2. 加载您要发送的帐户的数据。 一个帐户一次只能执行一个交易[5],并且有一个称为序列号的东西,这有助于POCChain验证交易的顺序。 交易的序列号需要与帐户的序列号匹配,因此您需要从网络获取帐户的当前序列号。
    AccountResponse sourceAccount = server.accounts().account(source);
    
    在构建交易时,SDK将自动递增帐户的序列号,因此如果要执行第二个交易,则无需再次检索此信息。
  3. 开始构建交易。 这需要一个帐户对象,而不仅仅是帐户ID,因为它会增加帐户的序列号。
    Transaction transaction = new Transaction.Builder(sourceAccount)
    
  4. 将付款操作添加到帐户。 请注意,您需要指定要发送的资产类型 - POCChain的“POCC”货币是帕克币,但您可以将任何类型的资产或货币(从美元到比特币)发送到您信任发行人的任何类型的资产。 兑换(详情如下方)。 但是现在,我们将坚持使用帕克币,在SDK中称为“Native”资产:
    .addOperation(new PaymentOperation.Builder(destination, new AssetTypeNative(), "10").build())
    
    您还应该注意,金额是一个字符串而不是一个数字。 使用极小分数或大值时,浮点数学会引入很小的不准确性。 由于并非所有系统都具有准确表示极小或大的小数的本机方式,因此POCChain使用字符串作为表示任何系统中确切数量的可靠方式。
  5. (可选)您可以将自己的元数据(称为Meno)添加到交易中。 POCChain对此数据不做任何操作,但您可以将其用于任何您想要的目的。 例如,如果您是代表其他人接收或发送付款的银行,您可能会在此处包含付款所针对的实际人员。
    .addMemo(Memo.text("Test Transaction"));
    
  6. 既然交易具有所需的所有数据,您必须使用秘密种子对其进行加密签名。 这证明数据实际上来自你,而不是冒充你的人。
    transaction.sign(source);
    
  7. 最后,将它发送到POCChain网络!
    server.submitTransaction(transaction);
    

重要事项 由于存在错误,网络状况等原因,您可能无法收到Horizon服务器的响应。在这种情况下,无法确定交易状态。 这就是为什么你应该总是将构建的交易(或以XDR格式编码的交易)保存在变量或数据库中,如果你不知道它的状态,则重新提交它。 如果交易已成功应用于分块,Horizon将仅返回保存的结果,而不会再次尝试提交交易。 只有在交易状态未知(因此有可能被包含在分块中)的情况下才会重新提交到网络。

接收付款

您实际上不需要做任何事情来接收POCChain帐户的付款 - 如果付款人成功交易向您发送资产,这些资产将自动添加到您的帐户。

但是,你会想知道某人实际上已经付钱给你了。 如果您是代表其他人接受付款的银行,您需要找出发送给您的内容,以便您可以向预期收件人支付资金。 如果您经营零售业务,您需要知道您的客户在您交给他们的商品之前实际支付了您的费用。 如果您是一辆带有POCChain帐户的自动租赁汽车,您可能希望在该人员可以打开您的引擎之前验证您的前座位上的客户是否实际已付款。

一个简单的程序,监视网络的付款和打印每个可能看起来像:

Server server = new Server("https://horizon-testnet.stellar.org");
KeyPair account = KeyPair.fromAccountId("GC2BKLYOOYPDEFJKLKY6FNNRQMGFLVHJKQRGNSSRRGSMPGF32LHCQVGF");

// Create an API call to query payments involving the account.
PaymentsRequestBuilder paymentsRequest = server.payments().forAccount(account);

// If some payments have already been handled, start the results from the
// last seen payment. (See below in `handlePayment` where it gets saved.)
String lastToken = loadLastPagingToken();
if (lastToken != null) {
  paymentsRequest.cursor(lastToken);
}

// `stream` will send each recorded payment, one by one, then keep the
// connection open and continue to send you new payments as they occur.
paymentsRequest.stream(new EventListener<OperationResponse>() {
  @Override
  public void onEvent(OperationResponse payment) {
    // Record the paging token so we can start from here next time.
    savePagingToken(payment.getPagingToken());

    // The payments stream includes both sent and received payments. We only
    // want to process received payments here.
    if (payment instanceof PaymentOperationResponse) {
      if (((PaymentOperationResponse) payment).getTo().equals(account)) {
        return;
      }

      String amount = ((PaymentOperationResponse) payment).getAmount();

      Asset asset = ((PaymentOperationResponse) payment).getAsset();
      String assetName;
      if (asset.equals(new AssetTypeNative())) {
        assetName = "lumens";
      } else {
        StringBuilder assetNameBuilder = new StringBuilder();
        assetNameBuilder.append(((AssetTypeCreditAlphaNum) asset).getCode());
        assetNameBuilder.append(":");
        assetNameBuilder.append(((AssetTypeCreditAlphaNum) asset).getIssuer().getAccountId());
        assetName = assetNameBuilder.toString();
      }

      StringBuilder output = new StringBuilder();
      output.append(amount);
      output.append(" ");
      output.append(assetName);
      output.append(" from ");
      output.append(((PaymentOperationResponse) payment).getFrom().getAccountId());
      System.out.println(output.toString());
    }

  }
});

该计划有两个主要部分。 首先,您为涉及给定帐户的付款创建查询。 与POCChain中的大多数查询一样,这可能会返回大量项目,因此API会返回分页令牌,您可以稍后使用它从您之前停止的同一点开始查询。 在上面的示例中,保存和加载分页令牌的功能保留为空白,但在实际应用程序中,您需要将分页令牌保存到文件或数据库中,以便在程序保存时从中断处取出 崩溃或用户关闭它。

paymentsRequest.stream(new EventListener<OperationResponse>() {
  @Override
  public void onEvent(OperationResponse payment) {
    // Handle a payment
  }
});

其次,查询结果是流式传输的。 这是观察付款或其他交易的最简单方法。 每个现有付款都是通过流逐个发送的。 一旦发送了所有现有付款,流将保持打开状态,并在发送新付款时发送。

试一试:运行此程序,然后在另一个窗口中创建并提交付款。 您应该看到此程序记录付款。

paymentsRequest.stream(new EventListener<OperationResponse>() {
  @Override
  public void onEvent(OperationResponse payment) {
    // Handle a payment
  }
});

您还可以按组或页面请求付款。 处理完每一页付款后,您需要先申请下一个付款,直到没有剩余付款。

Page<OperationResponse> page = payments.execute();

for (OperationResponse operation : page.getRecords()) {
    // handle a payment
}

page = page.getNextPage();

以其他货币进行交易

关于POCChain网络的一个令人惊奇的事情是,您可以发送和接收许多类型的资产,例如美元,尼日利亚奈拉,比特币等数字货币,甚至是您自己的新资产。

虽然POCChain的本地资产(帕克币)相当简单,但所有其他资产都可以被视为特定帐户发放的信用。事实上,当您在POCChain网络上交易美元时,您实际上并不交易美元 - 您从特定帐户交易美元。这就是为什么上面示例中的资产同时具有代码发行者的原因。发行者是创建资产的帐户的ID。了解发布资产的帐户很重要 - 您需要相信,如果您想在POCChain网络上兑换美元以获得实际的美元账单,发行人将能够向您提供。因此,您通常只想信任主要金融机构代表本国货币的资产。

POCChain还支持作为一种资产发送的付款并作为另一种资产收到。您可以将Nigerian naira寄给在德国的朋友,并让他们领取欧元。这些多货币交易是通过内置的市场机制实现的,人们可以通过这种机制来买卖不同类型的资产。 Stellar会自动为您查找兑换货币的最佳人选,以便将您的naira兑换成欧元。该系统称为分布式交换

您可以在资产概述中阅读有关资产详细信息的更多信息。

接下来是什么?

既然您可以使用POCChain的API发送和接收付款,那么您就可以编写各种令人惊叹的财务软件了。 试用API的其他部分,然后阅读更详细的主题:

  • 成为Anchor
  • 分布服务器
  • Federation服务器
  • 合规管理服务器