public override Empty Play(SInt64Value input) { Assert(input.Value > 1, "Invalid money."); var playerInformation = State.PlayerInformation[Context.Sender]; Assert(playerInformation != null, "Not registered."); if (playerInformation == null) { return(new Empty()); } Context.LogDebug(() => $"Playing with amount {input.Value}"); State.TokenContract.TransferFrom.Send(new TransferFromInput { From = Context.Sender, To = Context.Self, Amount = input.Value, Symbol = BingoGameContractConstants.CardSymbol, Memo = "Play the game." }); playerInformation.BingoInfos.Add(new BingoInformation { PlayRoundNumber = State.ConsensusContract.GetCurrentRoundNumber.Call(new Empty()).Value, Amount = input.Value, PlayId = Context.TransactionId }); State.PlayerInformation[Context.Sender] = playerInformation; return(new Empty()); }
public override Empty SetTransactionSizeUnitPrice(SInt64Value input) { if (State.ZeroContract.Value == null) { State.ZeroContract.Value = Context.GetZeroSmartContractAddress(); } if (State.ParliamentAuthContract.Value == null) { State.ParliamentAuthContract.Value = Context.GetContractAddressByName(SmartContractConstants.ParliamentAuthContractSystemName); } var contractOwner = State.ZeroContract.GetContractAuthor.Call(Context.Self); Assert( contractOwner == Context.Sender || Context.Sender == State.ParliamentAuthContract.GetGenesisOwnerAddress.Call(new Empty()) || Context.Sender == Context.GetContractAddressByName(SmartContractConstants.EconomicContractSystemName), "No permission to set tx size unit price."); Context.Fire(new TransactionSizeFeeUnitPriceUpdated { UnitPrice = input.Value }); Context.LogDebug(() => $"SetTransactionSizeUnitPrice: {input.Value}"); State.TransactionFeeUnitPrice.Value = input.Value; return(new Empty()); }
public override Empty Deposit(SInt64Value input) { var playerInformation = State.PlayerInformation[Context.Sender]; Assert(playerInformation != null, $"User {Context.Sender} not registered before."); Assert(input.Value > 0, "At least you should buy 1 CARD."); var elfAmount = input.Value.Mul(1_0000_0000); State.TokenContract.TransferFrom.Send(new TransferFromInput { Symbol = Context.Variables.NativeSymbol, Amount = elfAmount, From = Context.Sender, To = Context.Self, Memo = "Thanks for recharging:)" }); State.TokenContract.Transfer.Send(new TransferInput { Symbol = BingoGameContractConstants.CardSymbol, Amount = input.Value, To = Context.Sender, Memo = "Now you are stronger:)" }); return(new Empty()); }
public override CrossChainBlockData GetIndexedCrossChainBlockDataByHeight(SInt64Value input) { var indexedCrossChainBlockData = State.IndexedCrossChainBlockData[input.Value]; Assert(indexedCrossChainBlockData != null); return(indexedCrossChainBlockData); }
public async Task QueryMinedBlockCountInCurrentTerm() { await PrepareConsensusWithCandidateEnvironment(); SInt64Value count = new SInt64Value { Value = 0 }; foreach (var bpInfo in MinersKeyPairs) { var input = new PublicKey { Hex = bpInfo.PublicKey.ToHex() }; var bytes = await Starter.CallContractMethodAsync(Starter.GetConsensusContractAddress(), nameof(ConsensusContract.QueryMinedBlockCountInCurrentTerm), input); count = SInt64Value.Parser.ParseFrom(bytes); if (count.Value > 0) { break; } } count.Value.ShouldBeGreaterThanOrEqualTo(1L); }
public async Task Get_RoundInformation() { //query return null { var input = new SInt64Value { Value = 2 }; var roundInformation = await Starter.CallContractMethodAsync(Starter.GetConsensusContractAddress(), nameof(ConsensusContract.GetRoundInformation), input); var round = Round.Parser.ParseFrom(roundInformation); round.ShouldBe(new Round()); } //query with result { var input = new SInt64Value { Value = 1 }; var roundInformation = await Starter.CallContractMethodAsync(Starter.GetConsensusContractAddress(), nameof(ConsensusContract.GetRoundInformation), input); var round = Round.Parser.ParseFrom(roundInformation); round.ShouldNotBeNull(); round.RoundNumber.ShouldBe(1); round.RealTimeMinersInformation.Count.ShouldBe(3); } }
public override SInt64Value Play(SInt64Value input) { Assert(input.Value > 1, "Invalid bet amount."); var playerInformation = State.PlayerInformation[Context.Sender]; Assert(playerInformation != null, $"User {Context.Sender} not registered before."); Context.LogDebug(() => $"Playing with amount {input.Value}"); State.TokenContract.TransferFrom.Send(new TransferFromInput { From = Context.Sender, To = Context.Self, Amount = input.Value, Symbol = BingoGameContractConstants.CardSymbol, Memo = "Enjoy!" }); var currentRound = State.ConsensusContract.GetCurrentRoundInformation.Call(new Empty()); playerInformation.Bouts.Add(new BoutInformation { // Record current round number. PlayRoundNumber = currentRound.RoundNumber, Amount = input.Value, PlayId = Context.TransactionId }); State.PlayerInformation[Context.Sender] = playerInformation; return(new SInt64Value { Value = CalculateWaitingMilliseconds(currentRound) }); }
public async Task GetTermNumberByRoundNumber() { await PrepareConsensusWithCandidateEnvironment(); var input = new SInt64Value() { Value = 1 }; var bytes = await Starter.CallContractMethodAsync(Starter.GetConsensusContractAddress(), nameof(ConsensusContract.GetTermNumberByRoundNumber), input); var termNumber = SInt64Value.Parser.ParseFrom(bytes).Value; termNumber.ShouldBe(0L); var roundBytes = await Starter.CallContractMethodAsync(Starter.GetConsensusContractAddress(), nameof(ConsensusContract.GetCurrentRoundNumber), new Empty()); var currentRoundNumber = SInt64Value.Parser.ParseFrom(roundBytes).Value; var termBytes = await Starter.CallContractMethodAsync(Starter.GetConsensusContractAddress(), nameof(ConsensusContract.GetCurrentTermNumber), new Empty()); var currentTermNumber = SInt64Value.Parser.ParseFrom(termBytes).Value; input.Value = currentRoundNumber; bytes = await Starter.CallContractMethodAsync(Starter.GetConsensusContractAddress(), nameof(ConsensusContract.GetTermNumberByRoundNumber), input); termNumber = SInt64Value.Parser.ParseFrom(bytes).Value; termNumber.ShouldBe(currentTermNumber); }
public override SInt64Value GetTermNumberByRoundNumber(SInt64Value input) { var map = State.TermNumberLookupField.Value.Map; Assert(map != null, "Term number not found."); var roundNumber = map?.OrderBy(p => p.Key).Last(p => input.Value >= p.Value).Key ?? (long)0; return(new SInt64Value { Value = roundNumber }); }
/// <summary> /// Initial miners can set blockchain age manually. /// For testing. /// </summary> /// <param name="input"></param> /// <returns></returns> public override Empty SetBlockchainAge(SInt64Value input) { Assert(TryToGetRoundInformation(1, out var firstRound), ContractErrorCode.GetErrorMessage(ContractErrorCode.NotFound, "Failed to get first round information")); Assert(firstRound.RealTimeMinersInformation.Keys.Contains(Context.RecoverPublicKey().ToHex()), ContractErrorCode.GetErrorMessage(ContractErrorCode.NoPermission, "No permission to change blockchain age.")); // Don't use `UpdateBlockchainAge` here. Because in testing, we can set blockchain age for free. State.AgeField.Value = input.Value; LogVerbose($"{Context.RecoverPublicKey().ToHex()} set blockchain age to {input.Value}"); return(new Empty()); }
public override CrossChainBlockData GetIndexedCrossChainBlockDataByHeight(SInt64Value input) { var crossChainBlockData = new CrossChainBlockData(); var indexedParentChainBlockData = State.LastIndexedParentChainBlockData.Value; if (indexedParentChainBlockData != null && indexedParentChainBlockData.LocalChainHeight == input.Value) { crossChainBlockData.ParentChainBlockData.AddRange(indexedParentChainBlockData.ParentChainBlockData); } var indexedSideChainBlockData = GetIndexedSideChainBlockDataByHeight(input); crossChainBlockData.SideChainBlockData.AddRange(indexedSideChainBlockData.SideChainBlockData); return(crossChainBlockData); }
/// <summary> /// Converts the serialized protobuf data to human friendly representation. /// </summary> /// <returns></returns> public byte[] ToFriendlyBytes() { switch (Type) { case Types.RetType.Bool: var boolval = new BoolValue(); ((IMessage)boolval).MergeFrom(this.Data); return(BitConverter.GetBytes(boolval.Value)); case Types.RetType.Int32: var sint32Val = new SInt32Value(); ((IMessage)sint32Val).MergeFrom(this.Data); return(GetFriendlyBytes(sint32Val.Value)); case Types.RetType.Uint32: var uint32Val = new UInt32Value(); ((IMessage)uint32Val).MergeFrom(this.Data); return(GetFriendlyBytes(uint32Val.Value)); case Types.RetType.Int64: var sint64Val = new SInt64Value(); ((IMessage)sint64Val).MergeFrom(this.Data); return(GetFriendlyBytes(sint64Val.Value)); case Types.RetType.Uint64: var uint64Val = new UInt64Value(); ((IMessage)uint64Val).MergeFrom(this.Data); return(GetFriendlyBytes(uint64Val.Value)); case Types.RetType.String: var stringVal = new StringValue(); ((IMessage)stringVal).MergeFrom(this.Data); return(GetFriendlyBytes(stringVal.Value)); case Types.RetType.Bytes: var bytesVal = new BytesValue(); ((IMessage)bytesVal).MergeFrom(this.Data); return(GetFriendlyBytes(bytesVal.Value.ToByteArray())); case Types.RetType.PbMessage: case Types.RetType.UserType: // Both are treated as bytes return(GetFriendlyBytes(Data.ToByteArray())); } return(new byte[0]); }
public async Task GetTermSnapshot() { await PrepareConsensusWithCandidateEnvironment(); var input = new SInt64Value { Value = 1 }; var bytes = await Starter.CallContractMethodAsync(Starter.GetConsensusContractAddress(), nameof(ConsensusContract.GetTermSnapshot), input); var termSnapshot = TermSnapshot.Parser.ParseFrom(bytes); termSnapshot.TermNumber.ShouldBe(input.Value); termSnapshot.EndRoundNumber.ShouldBe(input.Value + 1); termSnapshot.CandidatesSnapshot.Count.ShouldBe(MinersCount); }
public override Empty SendTransferFromAsInlineTx(SInt64Value input) { if (State.TokenContract.Value == null) { State.TokenContract.Value = Context.GetContractAddressByName(SmartContractConstants.TokenContractSystemName); } State.TokenContract.TransferFrom.Send(new TransferFromInput { From = Context.Sender, To = Context.Self, Amount = input.Value, Symbol = "ELF" }); return(new Empty()); }
public override ActionResult KeepWeights(SInt64Value input) { var oldTermNumber = input.Value; var totalWeights = State.TotalWeightsMap[oldTermNumber]; if (totalWeights > 0) { Context.LogDebug(() => "[Forwarding weights]"); AddWeights(new WeightsInfo() { TermNumber = oldTermNumber + 1, Weights = totalWeights }); } return(new ActionResult { Success = true }); }
/// <summary> /// Withdraw specific amount owed to the foundation. Only foundation can perform this action. /// </summary> /// <param name="input"></param> /// <returns></returns> public override Empty Withdraw(SInt64Value input) { var amount = input.Value; Assert(Context.Sender == State.FoundationAddress.Value, "Only foundation can withdraw token."); var owed = State.OwedToFoundation.Value; Assert(owed >= amount, "Too much to withdraw."); if (amount > 0) { State.TokenContract.Transfer.Send(new TransferInput { To = State.FoundationAddress.Value, Amount = amount, Symbol = Context.Variables.NativeSymbol, }); } State.OwedToFoundation.Value = owed.Sub(amount); return(new Empty()); }
public override Empty Deposit(SInt64Value input) { var information = State.PlayerInformation[Context.Sender]; Assert(information != null, "Not registered."); State.TokenContract.TransferFrom.Send(new TransferFromInput { Symbol = Context.Variables.NativeSymbol, Amount = input.Value, From = Context.Sender, // TODO: Created a profit item and To = ProfitItemVirtualAddress To = Context.Self, Memo = "Thanks for recharging." }); State.TokenContract.Transfer.Send(new TransferInput { Symbol = BingoGameContractConstants.CardSymbol, Amount = input.Value, To = Context.Sender, Memo = "Now you are stronger." }); return(new Empty()); }
public override Round GetRoundInformation(SInt64Value input) => TryToGetRoundInformation(input.Value, out var round) ? round : new Round();
/// <summary> /// Get total weights of a specific term. /// </summary> /// <param name="input"></param> /// <returns></returns> public override SInt64Value GetTermTotalWeights(SInt64Value input) { return(new SInt64Value { Value = State.TotalWeightsMap[input.Value] }); }
public override IndexedSideChainBlockData GetIndexedSideChainBlockDataByHeight(SInt64Value input) { var indexedSideChainBlockData = State.IndexedSideChainBlockData[input.Value]; return(indexedSideChainBlockData ?? new IndexedSideChainBlockData()); }
public override TermSnapshot GetTermSnapshot(SInt64Value input) { return(State.SnapshotMap[input.Value.ToInt64Value()]); }
public override Round GetRoundInformation(SInt64Value input) { return(TryToGetRoundInformation(input.Value, out var roundInfo) ? roundInfo : null); }
/// <summary> /// Get dividends of a specific term. /// </summary> /// <param name="input"></param> /// <returns></returns> public override SInt64Value GetTermDividends(SInt64Value input) { return(new SInt64Value { Value = State.DividendsMap[input.Value] }); }
public override CrossChainMerkleProofContext GetBoundParentChainHeightAndMerklePathByHeight(SInt64Value input) { var boundParentChainHeight = State.ChildHeightToParentChainHeight[input.Value]; Assert(boundParentChainHeight != 0); var merklePath = State.TxRootMerklePathInParentChain[input.Value]; Assert(merklePath != null); return(new CrossChainMerkleProofContext { MerklePathForParentChainRoot = merklePath, BoundParentChainHeight = boundParentChainHeight }); }
public override IndexedSideChainBlockData GetIndexedSideChainBlockDataByHeight(SInt64Value input) { var indexedSideChainBlockData = State.IndexedSideChainBlockData[input.Value]; Assert(indexedSideChainBlockData != null, "Side chain block data should not be null."); return(indexedSideChainBlockData); }