private void UnlockTokenAndResource(SideChainInfo sideChainInfo) { //Api.Assert(sideChainInfo.LockedAddress.Equals(Api.GetFromAddress()), "Unable to withdraw token or resource."); // unlock token var chainId = sideChainInfo.SideChainId; var balance = State.IndexingBalance[chainId]; if (balance != 0) { Transfer(new TransferInput { To = sideChainInfo.Proposer, Amount = balance, Symbol = Context.Variables.NativeSymbol }); } State.IndexingBalance[chainId] = 0; // unlock resource /*foreach (var resourceBalance in sideChainInfo.ResourceBalances) * { * Api.UnlockResource(resourceBalance.Amount, resourceBalance.Type); * }*/ }
/// <summary> /// Create side chain. It is a proposal result from system address. /// </summary> /// <param name="input"></param> /// <returns></returns> public override Int32Value CreateSideChain(CreateSideChainInput input) { // side chain creation should be triggered by organization address. AssertSideChainLifetimeControllerAuthority(Context.Sender); var proposedSideChainCreationRequestState = State.ProposedSideChainCreationRequestState[input.Proposer]; State.ProposedSideChainCreationRequestState.Remove(input.Proposer); var sideChainCreationRequest = input.SideChainCreationRequest; Assert( proposedSideChainCreationRequestState != null && proposedSideChainCreationRequestState.SideChainCreationRequest.Equals(sideChainCreationRequest), "Side chain creation failed without proposed data."); AssertValidSideChainCreationRequest(sideChainCreationRequest, input.Proposer); State.SideChainSerialNumber.Value = State.SideChainSerialNumber.Value.Add(1); var serialNumber = State.SideChainSerialNumber.Value; var chainId = GetChainId(serialNumber); State.AcceptedSideChainCreationRequest[chainId] = sideChainCreationRequest; // lock token ChargeSideChainIndexingFee(input.Proposer, sideChainCreationRequest.LockedTokenAmount, chainId); CreateSideChainToken(sideChainCreationRequest, chainId, input.Proposer); var sideChainInfo = new SideChainInfo { Proposer = input.Proposer, SideChainId = chainId, SideChainStatus = SideChainStatus.Active, IndexingPrice = sideChainCreationRequest.IndexingPrice, IsPrivilegePreserved = sideChainCreationRequest.IsPrivilegePreserved, CreationTimestamp = Context.CurrentBlockTime, CreationHeightOnParentChain = Context.CurrentHeight }; State.SideChainInfo[chainId] = sideChainInfo; State.CurrentSideChainHeight[chainId] = 0; var initialConsensusInfo = GetCurrentMiners(); State.SideChainInitialConsensusInfo[chainId] = new BytesValue { Value = initialConsensusInfo.ToByteString() }; Context.LogDebug(() => $"Initial miner list for side chain {chainId} :" + string.Join(",", initialConsensusInfo.MinerList.Pubkeys)); CreateOrganizationForIndexingFeePriceAdjustment(input.Proposer); Context.Fire(new SideChainCreatedEvent { ChainId = chainId, Creator = input.Proposer }); return(new Int32Value { Value = chainId }); }
/// <summary> /// Create side chain. It is a proposal result from system address. /// </summary> /// <param name="sideChainCreationRequest"></param> /// <returns></returns> public override SInt32Value CreateSideChain(SideChainCreationRequest sideChainCreationRequest) { // side chain creation should be triggered by organization address from parliament. CheckOwnerAuthority(); Assert(sideChainCreationRequest.LockedTokenAmount > 0 && sideChainCreationRequest.LockedTokenAmount > sideChainCreationRequest.IndexingPrice, "Invalid chain creation request."); var sideChainTokenInfo = new SideChainTokenInfo { TokenName = sideChainCreationRequest.SideChainTokenName, Symbol = sideChainCreationRequest.SideChainTokenSymbol, TotalSupply = sideChainCreationRequest.SideChainTokenTotalSupply, Decimals = sideChainCreationRequest.SideChainTokenDecimals, IsBurnable = sideChainCreationRequest.IsSideChainTokenBurnable }; AssertSideChainTokenInfo(sideChainTokenInfo); State.SideChainSerialNumber.Value = State.SideChainSerialNumber.Value.Add(1); var serialNumber = State.SideChainSerialNumber.Value; int chainId = GetChainId(serialNumber); // lock token and resource CreateSideChainToken(sideChainCreationRequest, sideChainTokenInfo, chainId); var sideChainInfo = new SideChainInfo { Proposer = Context.Origin, SideChainId = chainId, SideChainStatus = SideChainStatus.Active, SideChainCreationRequest = sideChainCreationRequest, CreationTimestamp = Context.CurrentBlockTime, CreationHeightOnParentChain = Context.CurrentHeight }; State.SideChainInfo[chainId] = sideChainInfo; State.CurrentSideChainHeight[chainId] = 0; var initialConsensusInfo = GetCurrentMiners(); State.SideChainInitialConsensusInfo[chainId] = new BytesValue { Value = initialConsensusInfo.ToByteString() }; Context.LogDebug(() => $"Initial miner list for side chain {chainId} :" + string.Join(",", initialConsensusInfo.MinerList.Pubkeys)); Context.LogDebug(() => $"RoundNumber {initialConsensusInfo.RoundNumber}"); Context.Fire(new CreationRequested() { ChainId = chainId, Creator = Context.Origin }); return(new SInt32Value() { Value = chainId }); }
/// <summary> /// Create side chain. It is a proposal result from system address. /// </summary> /// <param name="input"></param> /// <returns></returns> public override Int32Value CreateSideChain(CreateSideChainInput input) { // side chain creation should be triggered by organization address. AssertSideChainLifetimeControllerAuthority(Context.Sender); var proposedSideChainCreationRequestState = State.ProposedSideChainCreationRequestState[input.Proposer]; State.ProposedSideChainCreationRequestState.Remove(input.Proposer); var sideChainCreationRequest = input.SideChainCreationRequest; Assert( proposedSideChainCreationRequestState != null && proposedSideChainCreationRequestState.SideChainCreationRequest.Equals(sideChainCreationRequest), "Side chain creation failed without proposed data."); AssertValidSideChainCreationRequest(sideChainCreationRequest, input.Proposer); State.SideChainSerialNumber.Value = State.SideChainSerialNumber.Value.Add(1); var serialNumber = State.SideChainSerialNumber.Value; var chainId = GetChainId(serialNumber); State.AcceptedSideChainCreationRequest[chainId] = sideChainCreationRequest; // lock token ChargeSideChainIndexingFee(input.Proposer, sideChainCreationRequest.LockedTokenAmount, chainId); var sideChainInfo = new SideChainInfo { Proposer = input.Proposer, SideChainId = chainId, SideChainStatus = SideChainStatus.Active, IndexingPrice = sideChainCreationRequest.IndexingPrice, IsPrivilegePreserved = sideChainCreationRequest.IsPrivilegePreserved, CreationTimestamp = Context.CurrentBlockTime, CreationHeightOnParentChain = Context.CurrentHeight, IndexingFeeController = CreateDefaultOrganizationForIndexingFeePriceManagement(input.Proposer) }; State.SideChainInfo[chainId] = sideChainInfo; State.CurrentSideChainHeight[chainId] = 0; var chainInitializationData = GetChainInitializationData(sideChainInfo, sideChainCreationRequest); State.SideChainInitializationData[sideChainInfo.SideChainId] = chainInitializationData; Context.Fire(new SideChainCreatedEvent { ChainId = chainId, Creator = input.Proposer }); return(new Int32Value { Value = chainId }); }
private void UnlockTokenAndResource(SideChainInfo sideChainInfo) { // unlock token var chainId = sideChainInfo.SideChainId; var balance = GetSideChainIndexingFeeDeposit(chainId); if (balance <= 0) { return; } TransferDepositToken(new TransferInput { To = sideChainInfo.Proposer, Amount = balance, Symbol = Context.Variables.NativeSymbol }, chainId); }
private ChainInitializationData GetChainInitializationData(SideChainInfo sideChainInfo, SideChainCreationRequest sideChainCreationRequest) { SetContractStateRequired(State.TokenContract, SmartContractConstants.TokenContractSystemName); var res = new ChainInitializationData { CreationHeightOnParentChain = sideChainInfo.CreationHeightOnParentChain, ChainId = sideChainInfo.SideChainId, Creator = sideChainInfo.Proposer, CreationTimestamp = sideChainInfo.CreationTimestamp, ChainCreatorPrivilegePreserved = sideChainInfo.IsPrivilegePreserved, ParentChainTokenContractAddress = State.TokenContract.Value }; var initialConsensusInfo = GetInitialConsensusInformation(); res.ChainInitializationConsensusInfo = new ChainInitializationConsensusInfo { InitialConsensusData = initialConsensusInfo }; ByteString nativeTokenInformation = GetNativeTokenInfo().ToByteString(); res.NativeTokenInfoData = nativeTokenInformation; ByteString resourceTokenInformation = GetResourceTokenInfo().ToByteString(); res.ResourceTokenInfo = new ResourceTokenInfo { ResourceTokenListData = resourceTokenInformation, InitialResourceAmount = { sideChainCreationRequest.InitialResourceAmount } }; if (IsPrimaryTokenNeeded(sideChainCreationRequest)) { ByteString sideChainTokenInformation = GetTokenInfo(sideChainCreationRequest.SideChainTokenCreationRequest.SideChainTokenSymbol).ToByteString(); res.ChainPrimaryTokenInfo = new ChainPrimaryTokenInfo { ChainPrimaryTokenData = sideChainTokenInformation, SideChainTokenInitialIssueList = { sideChainCreationRequest.SideChainTokenInitialIssueList }, }; } return(res); }
private void UnlockTokenAndResource(SideChainInfo sideChainInfo) { // unlock token var chainId = sideChainInfo.SideChainId; var balance = State.IndexingBalance[chainId]; if (balance != 0) { Transfer(new TransferInput { To = sideChainInfo.Proposer, Amount = balance, Symbol = Context.Variables.NativeSymbol }); } State.IndexingBalance[chainId] = 0; }
public byte[] CreateSideChain(Hash chainId, Address lockedAddress, ulong lockedToken) { ulong serialNumber = _sideChainSerialNumber.Increment().Value; var info = new SideChainInfo { Owner = Api.GetTransaction().From, ChainId = chainId, SerialNumer = serialNumber, Status = SideChainStatus.Pending, LockedAddress = lockedAddress, LockedToken = lockedToken, CreationHeight = Api.GetCurerntHeight() + 1 }; _sideChainInfos[chainId] = info; new SideChainCreationRequested() { ChainId = chainId, Creator = Api.GetTransaction().From }.Fire(); return(chainId.DumpByteArray()); }
/// <summary> /// Request from normal address to create side chain. /// </summary> /// <param name="input"></param> /// <returns></returns> public override RequestChainCreationOutput RequestChainCreation(SideChainCreationRequest input) { // no need to check authority since invoked in transaction from normal address Assert(input.LockedTokenAmount > 0 && input.LockedTokenAmount > input.IndexingPrice && !input.ContractCode.IsEmpty, "Invalid chain creation request."); State.SideChainSerialNumber.Value = State.SideChainSerialNumber.Value + 1; var serialNumber = State.SideChainSerialNumber.Value; int chainId = ChainHelpers.GetChainId(serialNumber); var info = State.SideChainInfos[chainId]; Assert(info == null, "Chain creation request already exists."); // lock token and resource LockTokenAndResource(input, chainId); // side chain creation proposal Hash proposalId = Propose(RequestChainCreationWaitingPeriod, Context.Self, nameof(CreateSideChain), new SInt32Value { Value = chainId }); // request.ProposalHash = hash; var sideChainInfo = new SideChainInfo { Proposer = Context.Sender, SideChainId = chainId, SideChainStatus = SideChainStatus.Review, SideChainCreationRequest = input }; State.SideChainInfos[chainId] = sideChainInfo; return(new RequestChainCreationOutput { ChainId = chainId, ProposalId = proposalId }); }