我正在尝试使用 Hedera JavaScript SDK
复制以下场景此场景涉及以下步骤:
TokenCreateTransaction
)您可以看到下面的实现:
import {
AccountId,
TokenCreateTransaction,
TokenType,
PrivateKey,
Client,
} from "@hashgraph/sdk";
// --- BOB (SIGNER account) ---
const BOB_ACCOUNTID = "0.0.5782085";
const BOB_PRIVATE_KEY = "";
// --- ALICE (PAYER account) ---
const ALICE_ACCOUNTID = "0.0.1079726";
const ALICE_PRIVATE_KEY = "";
async function main() {
// --- BOB (SIGNER account) ---
const bobPrivateKey = PrivateKey.fromStringED25519(BOB_PRIVATE_KEY);
const bobAccountId = AccountId.fromString(BOB_ACCOUNTID);
const bobClient = Client.forTestnet().setOperator(
bobAccountId,
bobPrivateKey
);
// --- ALICE (PAYER account) ---
const alicePrivateKey = PrivateKey.fromStringED25519(ALICE_PRIVATE_KEY);
const aliceAccountId = AccountId.fromString(ALICE_ACCOUNTID);
const aliceClient = Client.forTestnet().setOperator(
aliceAccountId,
alicePrivateKey
);
// 1. Bob creates the transaction object (e.g. a `TokenCreateTransaction`)
const transaction = new TokenCreateTransaction()
.setTokenName("New Token 123")
.setTokenSymbol("NT123")
.setTokenType(TokenType.FungibleCommon)
.setInitialSupply(2000)
.setTreasuryAccountId(bobAccountId);
// 2. Bob freezes and signs the transaction
const frozenTx = await transaction.freezeWith(bobClient);
const signedTx = await frozenTx.sign(bobPrivateKey);
// 3. Alice receives the signed transaction from Bob and adds her signature
const aliceSignedTx = await signedTx.sign(alicePrivateKey);
// 4. Alice executes the transaction and pays for the transaction fees
const txResponse = await aliceSignedTx.execute(aliceClient);
const receipt = await txResponse.getReceipt(aliceClient);
console.log("TransactionId: " + txResponse.transactionId);
console.log("Transaction status: " + receipt.status.toString());
console.log("Created tokenId: " + receipt.tokenId);
process.exit();
}
main();
当Bob冻结交易时就会出现问题,因为某些交易属性会被SDK自动修改。具体来说,
transactionId
和operatorAccountId
属性是根据冻结账户设置的,因此指定Bob为交易的付款人。
因此,即使Alice在流程结束时执行了交易,但付款人帐户实际上是Bob。
您可以在此处看到结果,其中 Bob (AccountId
0.0.5782085
) 是付款人帐户:https://hashscan.io/testnet/transaction/1698410500.114199003
我们如何确保Alice是支付交易费用的人,特别是当Bob是第一个冻结交易费用的人时?任何想法将不胜感激。
经过多次尝试,我找到了解决问题的方法。
Bob 创建交易时,需要使用
transactionId
方法设置 setTransactionId()
,如下所示:
const transaction = new TokenCreateTransaction()
.setTransactionId(transactionId)
transactionId
参数在此过程中至关重要。 Bob 必须使用 Alice 的 AccountId 创建它,以指定 Alice 作为交易的付款人。为了生成它,Bob 可以利用 generate()
中的 TransactionId class
方法。确保在代码开头导入该类:
import { TransactionId } from "@hashgraph/sdk";
const transactionId = TransactionId.generate(aliceAccountId)
这样,我们可以确保Bob发起、冻结和签署交易,同时指定Alice作为支付交易费用的付款账户。
重要提示:此流程要求 Bob 在创建交易之前知道 Alice 的 AccountId。
这里是所有更新的代码(只添加了2行,注释为:
<--- New Line
):
import {
AccountId,
TokenCreateTransaction,
TokenType,
PrivateKey,
Client,
TransactionId, // <--- New Line
} from "@hashgraph/sdk";
// --- BOB Account (SIGNER) ---
const BOB_ACCOUNTID = "0.0.5782085";
const BOB_PRIVATE_KEY = "";
// --- ALICE Account (PAYER) ---
const ALICE_ACCOUNTID = "0.0.1079726";
const ALICE_PRIVATE_KEY = "";
async function main() {
// --- BOB (SIGNER account) ---
const bobPrivateKey = PrivateKey.fromStringED25519(BOB_PRIVATE_KEY);
const bobAccountId = AccountId.fromString(BOB_ACCOUNTID);
const bobClient = Client.forTestnet().setOperator(
bobAccountId,
bobPrivateKey
);
// --- ALICE (PAYER account) ---
const alicePrivateKey = PrivateKey.fromStringED25519(ALICE_PRIVATE_KEY);
const aliceAccountId = AccountId.fromString(ALICE_ACCOUNTID);
const aliceClient = Client.forTestnet().setOperator(
aliceAccountId,
alicePrivateKey
);
// 1. Bob creates the transaction object (e.g. a `TokenCreateTransaction`)
// and sets a specific transactionId to designate Alice as the payer account
const transaction = new TokenCreateTransaction()
.setTokenName("New Token 123")
.setTokenSymbol("NT123")
.setTokenType(TokenType.FungibleCommon)
.setInitialSupply(2000)
.setTreasuryAccountId(bobAccountId)
.setTransactionId(TransactionId.generate(aliceAccountId)); // <--- New Line
// 2. Bob freezes and signs the transaction
const frozenTx = await transaction.freezeWith(bobClient);
const signedTx = await frozenTx.sign(bobPrivateKey);
// 3. Alice receives the signed transaction from Bob and adds her signature
const doubleSignedTx = await signedTx.sign(alicePrivateKey);
// 4. Alice executes the transaction and pays for the transaction fees
const txResponse = await doubleSignedTx.execute(aliceClient);
const receipt = await txResponse.getReceipt(aliceClient);
console.log("TransactionId: " + txResponse.transactionId);
console.log("Transaction status: " + receipt.status.toString());
console.log("Created tokenId: " + receipt.tokenId);
process.exit();
}
main();
您可以在此处看到结果,其中 Alice (AccountId
0.0.1079726
) 是付款人帐户:https://hashscan.io/testnet/transaction/1698423106.148047003
希望对某人有帮助!
冻结交易以准备签名需要设置交易ID(表示付款人)。这通常默认设置为冻结交易的帐户。因此,一旦交易被冻结,就无法更改付款人。所以如果不是冻结账户的话,需要在冻结时提前手动指定。
这在迭戈的回答中有所体现。