diff --git a/contract/AElf.Contracts.MultiToken/TokenContract_Actions.cs b/contract/AElf.Contracts.MultiToken/TokenContract_Actions.cs
index 249afc33ea..0159b7002c 100644
--- a/contract/AElf.Contracts.MultiToken/TokenContract_Actions.cs
+++ b/contract/AElf.Contracts.MultiToken/TokenContract_Actions.cs
@@ -32,8 +32,6 @@ public override Empty InitializeFromParentChain(InitializeFromParentChainInput i
///
public override Empty Create(CreateInput input)
{
- // can not call create on side chain
- Assert(State.SideChainCreator.Value == null, "Failed to create token if side chain creator already set.");
var inputSymbolType = GetCreateInputSymbolType(input.Symbol);
if (input.Owner == null)
{
@@ -52,6 +50,9 @@ private Empty CreateToken(CreateInput input, SymbolType symbolType = SymbolType.
AssertValidCreateInput(input, symbolType);
if (symbolType == SymbolType.Token || symbolType == SymbolType.NftCollection)
{
+ // can not call create on side chain
+ Assert(State.SideChainCreator.Value == null,
+ "Failed to create token if side chain creator already set.");
if (!IsAddressInCreateWhiteList(Context.Sender) &&
input.Symbol != TokenContractConstants.SeedCollectionSymbol)
{
@@ -468,7 +469,6 @@ public override Empty CrossChainCreateToken(CrossChainCreateTokenInput input)
Owner = validateTokenInfoExistsInput.Owner ?? validateTokenInfoExistsInput.Issuer
};
RegisterTokenInfo(tokenInfo);
-
Context.Fire(new TokenCreated
{
Symbol = validateTokenInfoExistsInput.Symbol,
@@ -485,6 +485,7 @@ public override Empty CrossChainCreateToken(CrossChainCreateTokenInput input)
return new Empty();
}
+
public override Empty RegisterCrossChainTokenContractAddress(RegisterCrossChainTokenContractAddressInput input)
{
CheckCrossChainTokenContractRegistrationControllerAuthority();
diff --git a/contract/AElf.Contracts.MultiToken/TokenContract_NFT_Actions.cs b/contract/AElf.Contracts.MultiToken/TokenContract_NFT_Actions.cs
index ac487122cb..2e242cf589 100644
--- a/contract/AElf.Contracts.MultiToken/TokenContract_NFT_Actions.cs
+++ b/contract/AElf.Contracts.MultiToken/TokenContract_NFT_Actions.cs
@@ -16,14 +16,15 @@ private Empty CreateNFTInfo(CreateInput input)
{
var nftCollectionInfo = AssertNftCollectionExist(input.Symbol);
input.IssueChainId = input.IssueChainId == 0 ? nftCollectionInfo.IssueChainId : input.IssueChainId;
- Assert(input.IssueChainId == nftCollectionInfo.IssueChainId,
+ Assert(
+ input.IssueChainId == nftCollectionInfo.IssueChainId && Context.ChainId == nftCollectionInfo.IssueChainId,
"NFT create ChainId must be collection's issue chainId");
-
var owner = nftCollectionInfo.Owner ?? nftCollectionInfo.Issuer;
Assert(Context.Sender == owner && owner == input.Owner, "NFT owner must be collection's owner");
if (nftCollectionInfo.Symbol == TokenContractConstants.SeedCollectionSymbol)
{
+ Assert(input.Decimals == 0 && input.TotalSupply == 1, "SEED must be unique.");
Assert(input.ExternalInfo.Value.TryGetValue(TokenContractConstants.SeedOwnedSymbolExternalInfoKey,
out var ownedSymbol), "OwnedSymbol does not exist.");
Assert(input.ExternalInfo.Value.TryGetValue(TokenContractConstants.SeedExpireTimeExternalInfoKey,
diff --git a/test/AElf.Contracts.MultiToken.Tests/BVT/NftApplicationTests.cs b/test/AElf.Contracts.MultiToken.Tests/BVT/NftApplicationTests.cs
index 8cec0aabbd..6c92193b21 100644
--- a/test/AElf.Contracts.MultiToken.Tests/BVT/NftApplicationTests.cs
+++ b/test/AElf.Contracts.MultiToken.Tests/BVT/NftApplicationTests.cs
@@ -184,6 +184,30 @@ private async Task> CreateNftCollectionAndNft(bool reuseItemId = tr
return symbols;
}
+ private async Task CreateNftFailed()
+ {
+ var collectionInfo = NftCollection1155Info;
+ collectionInfo.IssueChainId = 123;
+ var createCollectionRes = await CreateNftCollectionAsync(collectionInfo);
+ createCollectionRes.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined);
+ Nft1155Info.IssueChainId = 123;
+ var createNft2Res = await TokenContractStub.Create.SendWithExceptionAsync(new CreateInput
+ {
+ Symbol = $"{collectionInfo.Symbol}{Nft1155Info.Symbol}",
+ TokenName = Nft1155Info.TokenName,
+ TotalSupply = Nft1155Info.TotalSupply,
+ Decimals = Nft1155Info.Decimals,
+ Issuer = Nft1155Info.Issuer,
+ IsBurnable = Nft1155Info.IsBurnable,
+ IssueChainId = Nft1155Info.IssueChainId,
+ ExternalInfo = Nft1155Info.ExternalInfo,
+ Owner = Nft1155Info.Issuer
+ });
+ createNft2Res.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed);
+ createNft2Res.TransactionResult.Error.Contains("NFT create ChainId must be collection's issue chainId")
+ .ShouldBeTrue();
+ }
+
private void AssertTokenEqual(TokenCreated log, TokenInfo input)
{
Assert.Equal(log.TokenName, input.TokenName);
@@ -204,6 +228,12 @@ public async Task MultiTokenContract_Create_1155Nft_Test()
await CreateNftCollectionAndNft();
}
+ [Fact(DisplayName = "[MultiToken_Nft] Create 1155 nfts failed.")]
+ public async Task MultiTokenContract_Create_1155Nft_failed_Test()
+ {
+ await CreateNftFailed();
+ }
+
[Fact(DisplayName = "[MultiToken_Nft] Create 721 nfts.")]
public async Task MultiTokenContract_Create_721Nft_Test()
{
diff --git a/test/AElf.Contracts.MultiToken.Tests/BVT/TokenApplicationTests.cs b/test/AElf.Contracts.MultiToken.Tests/BVT/TokenApplicationTests.cs
index dba96e1023..0bb4ade958 100644
--- a/test/AElf.Contracts.MultiToken.Tests/BVT/TokenApplicationTests.cs
+++ b/test/AElf.Contracts.MultiToken.Tests/BVT/TokenApplicationTests.cs
@@ -999,16 +999,21 @@ public async Task Side_Chain_Creat_Token_Test()
});
await ApproveWithMinersAsync(proposalId);
await ParliamentContractStub.Release.SendAsync(proposalId);
- var createTokenRet = await TokenContractStub.Create.SendWithExceptionAsync(new CreateInput
- {
- Symbol = "ALI",
- TokenName = "Ali",
- Decimals = 4,
- TotalSupply = 100_000,
- Issuer = DefaultAddress,
- Owner = DefaultAddress
- });
- createTokenRet.TransactionResult.Error.ShouldContain(
+
+ proposalId = await CreateProposalAsync(TokenContractAddress,
+ defaultParliament, nameof(TokenContractStub.Create),
+ new CreateInput
+ {
+ Symbol = "ALI",
+ TokenName = "Ali",
+ Decimals = 4,
+ TotalSupply = 100_000,
+ Issuer = DefaultAddress,
+ Owner = DefaultAddress
+ });
+ await ApproveWithMinersAsync(proposalId);
+ var createTokenRe = await ParliamentContractStub.Release.SendWithExceptionAsync(proposalId);
+ createTokenRe.TransactionResult.Error.ShouldContain(
"Failed to create token if side chain creator already set.");
}