11. 限制
本节介绍了有关帐户的限制和对代币进行全局限制的相关内容。 在本章中,我们将限制现有帐户的权限,请创建一个新的一次性帐户来尝试此操作。
//Generating disposable accounts Carol
carol = sym.Account.generateNewAccount(networkType);
console.log(carol.address);
//Outlet FAUCET URL
console.log(
"https://testnet.symbol.tools/?recipient=" +
carol.address.plain() +
"&amount=100"
);
11.1 帐户限制
指定地址以限制进出交易
bob = sym.Account.generateNewAccount(networkType);
tx =
sym.AccountRestrictionTransaction.createAddressRestrictionModificationTransaction(
sym.Deadline.create(epochAdjustment),
sym.AddressRestrictionFlag.BlockIncomingAddress, //Address restriction flag
[bob.address], //Setup address
[], //Cancellation address
networkType
).setMaxFee(100);
signedTx = carol.sign(tx, generationHash);
await txRepo.announce(signedTx).toPromise();
对于 AddressRestrictionFlag(地址限制标志) 设置如下。
{1: 'AllowIncomingAddress', 16385: 'AllowOutgoingAddress', 32769: 'BlockIncomingAddress', 49153: 'BlockOutgoingAddress'}
除了 AllowIncomingAddress 之外,可以使用以下的标志(AddressRestrictionFlag):
- AllowIncomingAddress:仅允许来自特定地址的传入交易
- AllowOutgoingAddress:只允许传出交易到特定地址
- BlockIncomingAddress:拒绝来自指定地址的传入交易
- BlockOutgoingAddress:禁止向特定地址发出交易
接收指定马赛克的限制
mosaicId = new sym.MosaicId("72C0212E67A08BCE"); //Testnet XYM
tx =
sym.AccountRestrictionTransaction.createMosaicRestrictionModificationTransaction(
sym.Deadline.create(epochAdjustment),
sym.MosaicRestrictionFlag.BlockMosaic, //Mosaic restriction flag
[mosaicId], //Setup mosaic
[], //Cancellation mosaic
networkType
).setMaxFee(100);
signedTx = carol.sign(tx, generationHash);
await txRepo.announce(signedTx).toPromise();
MosaicRestrictionFlag(马赛克限制标志) 设置如下。
{2: 'AllowMosaic', 32770: 'BlockMosaic'}
- AllowMosaic:只允许接收包含指定马赛克的交易
- BlockMosaic:拒绝包含指定马赛克的传入交易
没有专门限制 马赛克 外发交易的功能。 请注意,这与全局马赛克限制不应混淆,该限制限制了马赛克的行为,如下所述。
特定交易的限制
tx =
sym.AccountRestrictionTransaction.createOperationRestrictionModificationTransaction(
sym.Deadline.create(epochAdjustment),
sym.OperationRestrictionFlag.AllowOutgoingTransactionType,
[sym.TransactionType.ACCOUNT_OPERATION_RESTRICTION], //Setup transaction
[], //Cancellation transaction
networkType
).setMaxFee(100);
signedTx = carol.sign(tx, generationHash);
await txRepo.announce(signedTx).toPromise();
OperationRestrictionFlag(操作限制标志) 设置如下。
{16388: 'AllowOutgoingTransactionType', 49156: 'BlockOutgoingTransactionType'}
- AllowOutgoingTransactionType:只允许特定的交易类型
- BlockOutgoingTransactionType:仅针对特定交易类型禁止
交易收据无限制功能。可以指定的操作如下。
交易类型如下。
{16705: 'AGGREGATE_COMPLETE', 16707: 'VOTING_KEY_LINK', 16708: 'ACCOUNT_METADATA', 16712: 'HASH_LOCK', 16716: 'ACCOUNT_KEY_LINK', 16717: 'MOSAIC_DEFINITION', 16718: 'NAMESPACE_REGISTRATION', 16720: 'ACCOUNT_ADDRESS_RESTRICTION', 16721: 'MOSAIC_GLOBAL_RESTRICTION', 16722: 'SECRET_LOCK', 16724: 'TRANSFER', 16725: 'MULTISIG_ACCOUNT_MODIFICATION', 16961: 'AGGREGATE_BONDED', 16963: 'VRF_KEY_LINK', 16964: 'MOSAIC_METADATA', 16972: 'NODE_KEY_LINK', 16973: 'MOSAIC_SUPPLY_CHANGE', 16974: 'ADDRESS_ALIAS', 16976: 'ACCOUNT_MOSAIC_RESTRICTION', 16977: 'MOSAIC_ADDRESS_RESTRICTION', 16978: 'SECRET_PROOF', 17220: 'NAMESPACE_METADATA', 17229: 'MOSAIC_SUPPLY_REVOCATION', 17230: 'MOSAIC_ALIAS'}
参考资料
17232: 禁止使用ACCOUNT_OPERATION_RESTRICTION限制。 这意味着如果指定了AllowOutgoingTransactionType,就必须包括ACCOUNT_OPERATION_RESTRICTION, 而如果指定了BlockOutgoingTransactionType,就不能包括ACCOUNT_OPERATION_RESTRICTION。
确认
检查有关您设置的限制的信息
resAccountRepo = repo.createRestrictionAccountRepository();
res = await resAccountRepo.getAccountRestrictions(carol.address).toPromise();
console.log(res);
市例演示
> AccountRestrictions
address: Address {address: 'TBXUTAX6O6EUVPB6X7OBNX6UUXBMPPAFX7KE5TQ', networkType: 152}
> restrictions: Array(2)
0: AccountRestriction
restrictionFlags: 32770
values: Array(1)
0: MosaicId
id: Id {lower: 1360892257, higher: 309702839}
1: AccountRestriction
restrictionFlags: 49153
values: Array(1)
0: Address {address: 'TCW2ZW7LVJMS4LWUQ7W6NROASRE2G2QKSBVCIQY', networkType: 152}
11.2 马赛克全局限制(Mosaic Global Restriction)
代币全局限制设置了转移代币的条件。 为专用于马赛克全局限制的数字元数据分配给每个帐户。 相关马赛克只有进出账号都满足条件才能发送。
首先,设置必要的资料库。
nsRepo = repo.createNamespaceRepository();
resMosaicRepo = repo.createRestrictionMosaicRepository();
mosaicResService = new sym.MosaicRestrictionTransactionService(
resMosaicRepo,
nsRepo
);
创建具有全局限制的马赛克
将 restrictable 设置为 true 以在 Carol 中创建马赛克。
supplyMutable = true; //Availability of changes in supply
transferable = true; //Transferability to third parties
restrictable = true; //Availability of global restriction settings
revokable = true; //Revokability from the issuer
nonce = sym.MosaicNonce.createRandom();
mosaicDefTx = sym.MosaicDefinitionTransaction.create(
undefined,
nonce,
sym.MosaicId.createFromNonce(nonce, carol.address),
sym.MosaicFlags.create(supplyMutable, transferable, restrictable, revokable),
0, //divisibility
sym.UInt64.fromUint(0), //duration
networkType
);
//Mosaic change
mosaicChangeTx = sym.MosaicSupplyChangeTransaction.create(
undefined,
mosaicDefTx.mosaicId,
sym.MosaicSupplyChangeAction.Increase,
sym.UInt64.fromUint(1000000),
networkType
);
//Mosaic Global Restriction
key = sym.KeyGenerator.generateUInt64Key("KYC"); // restrictionKey
mosaicGlobalResTx = await mosaicResService
.createMosaicGlobalRestrictionTransaction(
undefined,
networkType,
mosaicDefTx.mosaicId,
key,
"1",
sym.MosaicRestrictionType.EQ
)
.toPromise();
aggregateTx = sym.AggregateTransaction.createComplete(
sym.Deadline.create(epochAdjustment),
[
mosaicDefTx.toAggregate(carol.publicAccount),
mosaicChangeTx.toAggregate(carol.publicAccount),
mosaicGlobalResTx.toAggregate(carol.publicAccount),
],
networkType,
[]
).setMaxFeeForAggregate(100, 0);
signedTx = carol.sign(aggregateTx, generationHash);
await txRepo.announce(signedTx).toPromise();
MosaicRestrictionType (代币限制类型)如下。
{0: 'NONE', 1: 'EQ', 2: 'NE', 3: 'LT', 4: 'LE', 5: 'GT', 6: 'GE'}
Operator | Abbreviation | English |
---|---|---|
= | EQ | equal to |
!= | NE | not equal to |
< | LT | less than |
<= | LE | less than or equal to |
> | GT | greater than |
<= | GE | greater than or equal to |
对帐户应用马赛克限制
将针对 Mosaic 全局限制的资格信息添加到 Carol 和 Bob。 对已经拥有的马赛克没有限制,因为这些限制适用于传入和传出交易。
为了成功传输,发送方和接收方都必须满足条件。 可以使用马赛克创建者的私钥对任何帐户进行限制,无需签名同意。
//Apply to Carol
carolMosaicAddressResTx = sym.MosaicAddressRestrictionTransaction.create(
sym.Deadline.create(epochAdjustment),
mosaicDefTx.mosaicId, // mosaicId
sym.KeyGenerator.generateUInt64Key("KYC"), // restrictionKey
carol.address, // address
sym.UInt64.fromUint(1), // newRestrictionValue
networkType,
sym.UInt64.fromHex("FFFFFFFFFFFFFFFF") //previousRestrictionValue
).setMaxFee(100);
signedTx = carol.sign(carolMosaicAddressResTx, generationHash);
await txRepo.announce(signedTx).toPromise();
//Apply to Bob
bob = sym.Account.generateNewAccount(networkType);
bobMosaicAddressResTx = sym.MosaicAddressRestrictionTransaction.create(
sym.Deadline.create(epochAdjustment),
mosaicDefTx.mosaicId, // mosaicId
sym.KeyGenerator.generateUInt64Key("KYC"), // restrictionKey
bob.address, // address
sym.UInt64.fromUint(1), // newRestrictionValue
networkType,
sym.UInt64.fromHex("FFFFFFFFFFFFFFFF") //previousRestrictionValue
).setMaxFee(100);
signedTx = carol.sign(bobMosaicAddressResTx, generationHash);
await txRepo.announce(signedTx).toPromise();
确认限制状态检查
查询节点以检查其限制状态。
res = await resMosaicRepo
.search({ mosaicId: mosaicDefTx.mosaicId })
.toPromise();
console.log(res);
市例演示
> data
> 0: MosaicGlobalRestriction
compositeHash: "68FBADBAFBD098C157D42A61A7D82E8AF730D3B8C3937B1088456432CDDB8373"
entryType: 1
> mosaicId: MosaicId
id: Id {lower: 2467167064, higher: 973862467}
> restrictions: Array(1)
0: MosaicGlobalRestrictionItem
key: UInt64 {lower: 2424036727, higher: 2165465980}
restrictionType: 1
restrictionValue: UInt64 {lower: 1, higher: 0}
> 1: MosaicAddressRestriction
compositeHash: "920BFD041B6D30C0799E06585EC5F3916489E2DDF47FF6C30C569B102DB39F4E"
entryType: 0
> mosaicId: MosaicId
id: Id {lower: 2467167064, higher: 973862467}
> restrictions: Array(1)
0: MosaicAddressRestrictionItem
key: UInt64 {lower: 2424036727, higher: 2165465980}
restrictionValue: UInt64 {lower: 1, higher: 0}
targetAddress: Address {address: 'TAZCST2RBXDSD3227Y4A6ZP3QHFUB2P7JQVRYEI', networkType: 152}
> 2: MosaicAddressRestriction
...
转账确认
通过传输马赛克检查限制状态。
//Success (Carol to Bob)
trTx = sym.TransferTransaction.create(
sym.Deadline.create(epochAdjustment),
bob.address,
[new sym.Mosaic(mosaicDefTx.mosaicId, sym.UInt64.fromUint(1))],
sym.PlainMessage.create(""),
networkType
).setMaxFee(100);
signedTx = carol.sign(trTx, generationHash);
await txRepo.announce(signedTx).toPromise();
//Failed (Carol to Dave)
dave = sym.Account.generateNewAccount(networkType);
trTx = sym.TransferTransaction.create(
sym.Deadline.create(epochAdjustment),
dave.address,
[new sym.Mosaic(mosaicDefTx.mosaicId, sym.UInt64.fromUint(1))],
sym.PlainMessage.create(""),
networkType
).setMaxFee(100);
signedTx = carol.sign(trTx, generationHash);
await txRepo.announce(signedTx).toPromise();
失败将导致以下错误状态。
{"hash":"E3402FB7AE21A6A64838DDD0722420EC67E61206C148A73B0DFD7F8C098062FA","code":"Failure_RestrictionMosaic_Account_Unauthorized","deadline":"12371602742","group":"failed"}
11.3 使用提示
"账户限制"和"代币全局限制"功能可用于控制Symbol账户和代币的属性。这些限制的灵活性使Symbol区块链具备在实际应用场景中实现的潜力。例如,为了遵守法律法规或避免交易某个特定业务发行的代币,可能需要限制某个代币的转移。账户也可以限制,以限制特定代币的入账交易或来自特定用户的交易,从而避免垃圾邮件或恶意交易,为Symbol用户提供额外的安全保障。
账号烧毁
通过使用"AllowIncomingAddress"来限制仅从指定地址接收资金,然后将整个 XYM 余额发送到另一个帐户,用户可以显式地创建一个难以单独操作的帐户,即使拥有私钥也很难。 (请注意,可以通过授权最低费用为 0 的节点进行授权。)
马赛克锁
如果发行的马赛克设置为不可转让,而创建者禁止将马赛克接收到其帐户,那么该马赛克将被锁定,无法从接收者的帐户移动。
所有权证明
所有权证明已在有关马赛克的章节中解释。通过利用马赛克全局限制,可以创建一种只能由那些已经通过KYC过程的帐户拥有和流通的马赛克,从而创建一个独特的经济区域,只有拥有者可以参与。