public void Query( [Argument( Name = "KV-STORE", Description = KVStoreArgumentDescription)] string kvStoreUri, [Argument( Name = "STATE-ROOT-HASH", Description = "The state root hash to compare.")] string stateRootHashHex, [Argument( Name = "STATE-KEY", Description = "The key of the state to query.")] string stateKey, [FromService] IConfigurationService <ToolConfiguration> configurationService) { ToolConfiguration toolConfiguration = configurationService.Load(); kvStoreUri = ConvertKVStoreUri(kvStoreUri, toolConfiguration); IKeyValueStore keyValueStore = LoadKVStoreFromURI(kvStoreUri); var trie = new MerkleTrie( keyValueStore, HashDigest <SHA256> .FromString(stateRootHashHex)); byte[] stateKeyBytes = Encoding.UTF8.GetBytes(stateKey); if (trie.TryGet( stateKeyBytes, out IValue? value) && value is { })
public void Export( [Argument( Name = "KV-STORE", Description = KVStoreArgumentDescription)] string kvStoreUri, [Argument( Name = "STATE-ROOT-HASH", Description = "The state root hash to compare.")] string stateRootHashHex, [FromService] IConfigurationService <ToolConfiguration> configurationService) { ToolConfiguration toolConfiguration = configurationService.Load(); kvStoreUri = ConvertKVStoreUri(kvStoreUri, toolConfiguration); IKeyValueStore keyValueStore = LoadKVStoreFromURI(kvStoreUri); var trie = new MerkleTrie( keyValueStore, HashDigest <SHA256> .FromString(stateRootHashHex)); var codec = new Codec(); ImmutableDictionary <string, byte[]> decoratedStates = trie.ListAllStates() .ToImmutableDictionary( pair => Encoding.UTF8.GetString(pair.Key.ToArray()), pair => codec.Encode(pair.Value)); Console.WriteLine(JsonSerializer.Serialize(decoratedStates)); }
public void Hash() { Currency currency = new Currency(ticker: "GOLD", decimalPlaces: 2, minter: AddressA); HashDigest <SHA1> expected = HashDigest <SHA1> .FromString("81446cd346c1be9e686835742bfd3772194dea21"); AssertBytesEqual(expected, currency.Hash); currency = new Currency( ticker: "NCG", decimalPlaces: 8, minters: ImmutableHashSet.Create(AddressA, AddressB) ); expected = HashDigest <SHA1> .FromString("42ce3a098fe14084e89d3d4449f56126693aeed1"); AssertBytesEqual(expected, currency.Hash); currency = new Currency( ticker: "FOO", decimalPlaces: 0, minters: ImmutableHashSet <Address> .Empty ); expected = HashDigest <SHA1> .FromString("801990ea2885bd51eebca0e826cc0e27f0917a9b"); AssertBytesEqual(expected, currency.Hash); currency = new Currency(ticker: "BAR", decimalPlaces: 1, minter: null); expected = HashDigest <SHA1> .FromString("da42781871890f1e1b7d6f49c7f2733d3ba7b8bd"); AssertBytesEqual(expected, currency.Hash); }
public void Hash() { Currency currency = new Currency(ticker: "GOLD", minter: AddressA); HashDigest <SHA1> expected = HashDigest <SHA1> .FromString("2ce0b92ff1c5e5631d73370ad2c45920c1ba9755"); AssertBytesEqual(expected, currency.Hash); currency = new Currency( ticker: "NCG", minters: ImmutableHashSet.Create(AddressA, AddressB) ); expected = HashDigest <SHA1> .FromString("1c978d2f95370e73ffe640e85baa51a6514122a3"); AssertBytesEqual(expected, currency.Hash); currency = new Currency( ticker: "FOO", minters: ImmutableHashSet <Address> .Empty ); expected = HashDigest <SHA1> .FromString("fccaa58d80d8388190ece63718af395d14857f88"); AssertBytesEqual(expected, currency.Hash); currency = new Currency(ticker: "BAR", minter: null); expected = HashDigest <SHA1> .FromString("fd19100c874c062b73b9a93dbffeae7ae506ecd4"); AssertBytesEqual(expected, currency.Hash); }
public void DeriveFrom() { byte[] foo = { 0x66, 0x6f, 0x6f }, bar = { 0x62, 0x61, 0x72 }; Assert.Equal( HashDigest <SHA1> .FromString("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"), HashDigest <SHA1> .DeriveFrom(foo) ); Assert.Equal( HashDigest <SHA1> .DeriveFrom(foo), HashDigest <SHA1> .DeriveFrom(ImmutableArray.Create(foo)) ); Assert.Equal( HashDigest <SHA1> .DeriveFrom(foo), HashDigest <SHA1> .DeriveFrom(foo.AsSpan()) ); Assert.Equal( HashDigest <SHA1> .FromString("62cdb7020ff920e5aa642c3d4066950dd1f01f4d"), HashDigest <SHA1> .DeriveFrom(bar) ); Assert.Equal( HashDigest <MD5> .FromString("acbd18db4cc2f85cedef654fccc4a4d8"), HashDigest <MD5> .DeriveFrom(foo) ); Assert.Equal( HashDigest <MD5> .FromString("37b51d194a7513e45b56f6524f2d51f2"), HashDigest <MD5> .DeriveFrom(bar) ); }
public BlockQuery() { Field <NonNullGraphType <ListGraphType <NonNullGraphType <BlockType <T> > > > >( "blocks", arguments: new QueryArguments( new QueryArgument <BooleanGraphType> { Name = "desc", DefaultValue = false, }, new QueryArgument <IntGraphType> { Name = "offset", DefaultValue = 0, }, new QueryArgument <IntGraphType> { Name = "limit" }, new QueryArgument <BooleanGraphType> { Name = "excludeEmptyTxs", DefaultValue = false, }, new QueryArgument <AddressType> { Name = "miner" } ), resolve: context => { bool desc = context.GetArgument <bool>("desc"); long offset = context.GetArgument <long>("offset"); int?limit = context.GetArgument <int?>("limit", null); bool excludeEmptyTxs = context.GetArgument <bool>("excludeEmptyTxs"); Address?miner = context.GetArgument <Address?>("miner", null); return(Query <T> .ListBlocks(desc, offset, limit, excludeEmptyTxs, miner)); } ); Field <BlockType <T> >( "block", arguments: new QueryArguments( new QueryArgument <IdGraphType> { Name = "hash" } ), resolve: context => { HashDigest <SHA256> hash = HashDigest <SHA256> .FromString( context.GetArgument <string>("hash")); return(Query <T> .GetBlock(hash)); } ); Name = "BlockQuery"; }
public BlocksQuery(BlockChain <T> chain) { Field <ListGraphType <BlockType <T> > >( "blocks", arguments: new QueryArguments( new QueryArgument <BooleanGraphType> { Name = "desc", DefaultValue = false, }, new QueryArgument <IntGraphType> { Name = "offset", DefaultValue = 0, }, new QueryArgument <IntGraphType> { Name = "limit" }, new QueryArgument <BooleanGraphType> { Name = "empty", DefaultValue = true, } ), resolve: context => { bool desc = context.GetArgument <bool>("desc"); int offset = context.GetArgument <int>("offset"); int?limit = context.GetArgument <int?>("limit", null); bool empty = context.GetArgument <bool>("empty"); return(ListBlocks(desc, offset, limit, empty)); } ); Field <BlockType <T> >( "block", arguments: new QueryArguments( new QueryArgument <IdGraphType> { Name = "hash" } ), resolve: context => { HashDigest <SHA256> hash = HashDigest <SHA256> .FromString( context.GetArgument <string>("hash")); return(_chain.Blocks[hash]); } ); _chain = chain; Name = "BlockQuery"; }
public void FromStringWorks() { var b = new byte[20] { 0x45, 0xa2, 0x21, 0x87, 0xe2, 0xd8, 0x85, 0x0b, 0xb3, 0x57, 0x88, 0x69, 0x58, 0xbc, 0x3e, 0x85, 0x60, 0x92, 0x9c, 0xcc, }; var expected = new HashDigest <SHA1>(b); HashDigest <SHA1> actual = HashDigest <SHA1> .FromString( "45a22187e2d8850bb357886958bc3e8560929ccc"); Assert.Equal(actual, expected); }
public IActionResult getBlock(string hash) { Block <T> block; HashDigest <SHA256> blockHash; Blockchain <T> chain = GetBlockchain(); try { blockHash = HashDigest <SHA256> .FromString(hash); } catch (ArgumentException) { return(BadRequest(new Dictionary <string, string> { { "message", $"\"{hash}\" is not a proper hash." } })); } try { block = chain.Blocks[blockHash]; } catch (KeyNotFoundException) { return(NotFound(new Dictionary <string, string> { { "message", $"block(\"{hash}\") is not found" } })); } var model = new BlockViewModel { Index = block.Index, Difficulty = block.Difficulty, Nonce = block.Nonce.ToString(), PreviousHash = block.PreviousHash.ToString(), RewardBeneficiary = block.RewardBeneficiary?.ToHex(), Timestamp = block.Timestamp.ToString(TimestampFormat), TxIds = (block.Transactions .OrderByDescending(tx => tx.Timestamp) .Select(tx => new Dictionary <string, string> { { "id", tx.Id.ToString() }, { "timestamp", tx.Timestamp.ToString(TimestampFormat) } })).ToList() }; return(Ok(model)); }
public void Diff( [Argument( Name = "KV-STORE", Description = KVStoreArgumentDescription)] string kvStoreUri, [Argument( Name = "STATE-ROOT-HASH", Description = "The state root hash to compare.")] string stateRootHashHex, [Argument( Name = "OTHER-KV-STORE", Description = KVStoreArgumentDescription)] string otherKvStoreUri, [Argument( Name = "OTHER-STATE-ROOT-HASH", Description = "Another state root hash to compare.")] string otherStateRootHashHex, [FromService] IConfigurationService <ToolConfiguration> configurationService) { ToolConfiguration toolConfiguration = configurationService.Load(); kvStoreUri = ConvertKVStoreUri(kvStoreUri, toolConfiguration); otherKvStoreUri = ConvertKVStoreUri(otherKvStoreUri, toolConfiguration); IKeyValueStore keyValueStore = LoadKVStoreFromURI(kvStoreUri); IKeyValueStore otherKeyValueStore = LoadKVStoreFromURI(otherKvStoreUri); var trie = new MerkleTrie( keyValueStore, HashDigest <SHA256> .FromString(stateRootHashHex)); var otherTrie = new MerkleTrie( otherKeyValueStore, HashDigest <SHA256> .FromString(otherStateRootHashHex)); foreach (var group in trie.DifferentNodes(otherTrie)) { Console.Error.Write("Path: "); Console.WriteLine(Encoding.UTF8.GetString(ByteUtil.ParseHex(group.Key))); var values = group.ToArray(); foreach (var pair in values) { Console.Error.Write("At "); Console.WriteLine(ByteUtil.Hex(pair.Root.ToByteArray())); Console.WriteLine(pair.Value.Inspection); } Console.WriteLine(); } }
public void FromStringWorks() { var b = new byte[20] { 0x45, 0xa2, 0x21, 0x87, 0xe2, 0xd8, 0x85, 0x0b, 0xb3, 0x57, 0x88, 0x69, 0x58, 0xbc, 0x3e, 0x85, 0x60, 0x92, 0x9c, 0xcc, }; var expected = new HashDigest <SHA1>(b); HashDigest <SHA1> actual = HashDigest <SHA1> .FromString( "45a22187e2d8850bb357886958bc3e8560929ccc"); Assert.Equal(expected, actual); Assert.Throws <ArgumentNullException>( () => HashDigest <SHA1> .FromString(null) ); }
public void Diff( [Argument( Name = "KV-STORE", Description = KVStoreArgumentDescription)] string kvStoreUri, [Argument( Name = "STATE-ROOT-HASH", Description = "The state root hash to compare.")] string stateRootHashHex, [Argument( Name = "OTHER-KV-STORE", Description = KVStoreArgumentDescription)] string otherKvStoreUri, [Argument( Name = "OTHER-STATE-ROOT-HASH", Description = "Another state root hash to compare.")] string otherStateRootHashHex, [FromService] IConfigurationService <ToolConfiguration> configurationService) { ToolConfiguration toolConfiguration = configurationService.Load(); kvStoreUri = ConvertKVStoreUri(kvStoreUri, toolConfiguration); otherKvStoreUri = ConvertKVStoreUri(otherKvStoreUri, toolConfiguration); IKeyValueStore keyValueStore = LoadKVStoreFromURI(kvStoreUri); IKeyValueStore otherKeyValueStore = LoadKVStoreFromURI(otherKvStoreUri); var trie = new MerkleTrie( keyValueStore, HashDigest <SHA256> .FromString(stateRootHashHex)); var otherTrie = new MerkleTrie( otherKeyValueStore, HashDigest <SHA256> .FromString(otherStateRootHashHex)); var codec = new Codec(); HashDigest <SHA256> originRootHash = trie.Hash; HashDigest <SHA256> otherRootHash = otherTrie.Hash; string originRootHashHex = ByteUtil.Hex(originRootHash.ByteArray); string otherRootHashHex = ByteUtil.Hex(otherRootHash.ByteArray); foreach (var(key, originValue, otherValue) in trie.DifferentNodes(otherTrie)) { var data = new DiffData(ByteUtil.Hex(key.ByteArray), new Dictionary <string, string> {
public void Diff( [Argument( Name = "KV-STORE", Description = KVStoreArgumentDescription)] string kvStoreUri, [Argument( Name = "STATE-ROOT-HASH", Description = "The state root hash to compare.")] string stateRootHashHex, [Argument( Name = "OTHER-KV-STORE", Description = KVStoreArgumentDescription)] string otherKvStoreUri, [Argument( Name = "OTHER-STATE-ROOT-HASH", Description = "Another state root hash to compare.")] string otherStateRootHashHex, [FromService] IConfigurationService <ToolConfiguration> configurationService) { ToolConfiguration toolConfiguration = configurationService.Load(); kvStoreUri = ConvertKVStoreUri(kvStoreUri, toolConfiguration); otherKvStoreUri = ConvertKVStoreUri(otherKvStoreUri, toolConfiguration); IKeyValueStore keyValueStore = LoadKVStoreFromURI(kvStoreUri); IKeyValueStore otherKeyValueStore = LoadKVStoreFromURI(otherKvStoreUri); var trie = new MerkleTrie( keyValueStore, HashDigest <SHA256> .FromString(stateRootHashHex)); var otherTrie = new MerkleTrie( otherKeyValueStore, HashDigest <SHA256> .FromString(otherStateRootHashHex)); var codec = new Codec(); Dictionary <string, Dictionary <string, string> > dictionary = trie.DifferentNodes(otherTrie).ToDictionary( group => group.Key, group => group.ToDictionary( pair => ByteUtil.Hex(pair.Root.ByteArray), pair => ByteUtil.Hex(codec.Encode(pair.Value)))); Console.Write(JsonSerializer.Serialize(dictionary)); }
public void HashDigestDisallowsIncorrectSizedBytes() { for (int i = 0; i < 22; ++i) { if (i == 20) { new HashDigest <SHA1>(new byte[i]); HashDigest <SHA1> .FromString(new string('0', i * 2)); continue; } Assert.Throws <ArgumentOutOfRangeException>( () => new HashDigest <SHA1>(new byte[i]) ); Assert.Throws <ArgumentOutOfRangeException>( () => HashDigest <SHA1> .FromString(new string('0', i * 2)) ); } }
public BlockFixture() { Miner = TestUtils.GenesisMiner; Genesis = TestUtils.MineGenesisBlock <PolymorphicAction <BaseAction> >( hashAlgorithmGetter: GetHashAlgorithm, protocolVersion: ProtocolVersion, miner: Miner, stateRootHash: HashDigest <SHA256> .FromString( "e2e938f9d8af0a20d16d1c233fc4e8f39157145d003565807e4055ce6b5a0121") ); TxFixture = new TxFixture(Genesis.Hash); Next = TestUtils.MineNextBlock( Genesis, miner: Miner, hashAlgorithmGetter: GetHashAlgorithm, nonce: new byte[] { 0x02, 0x00, 0x00, 0x00 }, protocolVersion: ProtocolVersion, stateRootHash: HashDigest <SHA256> .FromString( "6a648da9e91c21aa22bdae4e35c338406392aad0db4a0f998c01a7d7973cb8aa") ); byte[] hasTxNonce = { 0x5c, 0x77, 0x74, 0xc2, 0x39, 0x69, 0x37, 0x51, 0x87, 0xa5, }; HasTx = TestUtils.MineNextBlock( Next, miner: Miner, hashAlgorithmGetter: GetHashAlgorithm, txs: new List <Transaction <PolymorphicAction <BaseAction> > > { TxFixture.TxWithActions, }, nonce: hasTxNonce, protocolVersion: ProtocolVersion, stateRootHash: HashDigest <SHA256> .FromString( "aaeda4f1a6a4aee7fc9a29014cff005109176e83a8e5d28876f2d889680e6421") ); }
public BlockContentFixture() { TimeSpan kst = TimeSpan.FromHours(9); GenesisKey = new PrivateKey(new byte[] { 0x9b, 0xf4, 0x66, 0x4b, 0xa0, 0x9a, 0x89, 0xfa, 0xeb, 0x68, 0x4b, 0x94, 0xe6, 0x9f, 0xfd, 0xe0, 0x1d, 0x26, 0xae, 0x14, 0xb5, 0x56, 0x20, 0x4d, 0x3f, 0x6a, 0xb5, 0x8f, 0x61, 0xf7, 0x84, 0x18, }); GenesisMetadata = new BlockMetadata { Index = 0, Timestamp = new DateTimeOffset(2021, 9, 6, 13, 46, 39, 123, kst), PublicKey = GenesisKey.PublicKey, Difficulty = 0, PreviousHash = null, TxHash = null, }; Genesis = new BlockContent <Arithmetic>(GenesisMetadata); GenesisHash = BlockHash.FromString( "341e8f360597d5bc45ab96aabc5f1b0608063f30af7bd4153556c9536a07693a" ); Block1Key = new PrivateKey(new byte[] { 0xfc, 0xf3, 0x0b, 0x33, 0x3d, 0x04, 0xcc, 0xfe, 0xb5, 0x62, 0xf0, 0x00, 0xa3, 0x2d, 0xf4, 0x88, 0xe7, 0x15, 0x49, 0x49, 0xd3, 0x1d, 0xdc, 0xac, 0x3c, 0xf9, 0x27, 0x8a, 0xcb, 0x57, 0x86, 0xc7, }); BlockMetadata1 = new BlockMetadata { Index = 1, Timestamp = new DateTimeOffset(2021, 9, 6, 17, 1, 9, 45, kst), PublicKey = Block1Key.PublicKey, Difficulty = 123, PreviousHash = GenesisHash, TxHash = HashDigest <SHA256> .FromString( "654698d34b6d9a55b0c93e4ffb2639278324868c91965bc5f96cb3071d6903a0" ), }; var block1Tx0Key = PrivateKey.FromString( "2d5c20079bc4b2e6eab9ecbb405da8ba6590c436edfb07b7d4466563d7dac096" ); Tx0InBlock1 = new Transaction <Arithmetic>( nonce: 0L, signer: block1Tx0Key.ToAddress(), publicKey: block1Tx0Key.PublicKey, genesisHash: GenesisHash, updatedAddresses: ImmutableHashSet <Address> .Empty.Add(block1Tx0Key.ToAddress()), timestamp: new DateTimeOffset(2021, 9, 6, 17, 0, 1, 1, kst), actions: new[] { Arithmetic.Add(10), Arithmetic.Add(50), Arithmetic.Sub(25), }, signature: ByteUtil.ParseHex( "30440220422c85ea44845a56253654d95595ad06d6f09f862ca71b97e986ecbb453eac" + "ae0220606e76276e40fa8f0795b880f712531fd6bd9db253bd8ab9c86aa4ab7d791d37" ) ); Tx0InBlock1.Validate(block1Tx0Key); var block1Tx1Key = PrivateKey.FromString( "105341c78dfb0dd313b961081630444c2586a1f01fb0c625368ffdc9136cfa30" ); Tx1InBlock1 = new Transaction <Arithmetic>( nonce: 1L, signer: block1Tx1Key.ToAddress(), publicKey: block1Tx1Key.PublicKey, genesisHash: GenesisHash, updatedAddresses: ImmutableHashSet <Address> .Empty.Add(block1Tx1Key.ToAddress()), timestamp: new DateTimeOffset(2021, 9, 6, 17, 0, 1, 1, kst), actions: new[] { Arithmetic.Add(30) }, signature: ByteUtil.ParseHex( "3045022100abe3caabf2a46a297f2e4496f2c46d7e2f723e75fc42025d19f3ed7fce382" + "d4e02200ffd36f7bef759b6c7ab43bc0f8959a0c463f88fd0f1faeaa209a8661506c4f0" ) ); Tx1InBlock1.Validate(block1Tx1Key); Block1 = new BlockContent <Arithmetic>( BlockMetadata1, new[] { Tx0InBlock1, Tx1InBlock1, } ); BlockMetadataPv0 = new BlockMetadata { ProtocolVersion = 0, Index = 0, Timestamp = new DateTimeOffset(2021, 9, 6, 13, 46, 39, 123, kst), Miner = GenesisKey.ToAddress(), Difficulty = 0, PreviousHash = null, TxHash = null, }; BlockPv0 = new BlockContent <Arithmetic>(BlockMetadataPv0); BlockPv1 = new BlockContent <Arithmetic>(Block1) { ProtocolVersion = 1, PublicKey = null, }; BlockMetadataPv1 = new BlockMetadata(BlockPv1); }
private static HashDigest <SHA256> H(string h) => HashDigest <SHA256> .FromString(h);
public void OnAfterDeserialize() { Value = HashDigest <T> .FromString(json); }
public BlockQuery() { Field <NonNullGraphType <ListGraphType <NonNullGraphType <BlockType <T> > > > >( "blocks", arguments: new QueryArguments( new QueryArgument <BooleanGraphType> { Name = "desc", DefaultValue = false, }, new QueryArgument <IntGraphType> { Name = "offset", DefaultValue = 0, }, new QueryArgument <IntGraphType> { Name = "limit" }, new QueryArgument <BooleanGraphType> { Name = "excludeEmptyTxs", DefaultValue = false, }, new QueryArgument <AddressType> { Name = "miner" } ), resolve: context => { bool desc = context.GetArgument <bool>("desc"); long offset = context.GetArgument <long>("offset"); int?limit = context.GetArgument <int?>("limit", null); bool excludeEmptyTxs = context.GetArgument <bool>("excludeEmptyTxs"); Address?miner = context.GetArgument <Address?>("miner", null); return(Query <T> .ListBlocks(desc, offset, limit, excludeEmptyTxs, miner)); } ); Field <BlockType <T> >( "block", arguments: new QueryArguments( new QueryArgument <IdGraphType> { Name = "hash" }, new QueryArgument <IdGraphType> { Name = "index" } ), resolve: context => { string hash = context.GetArgument <string>("hash"); long?index = context.GetArgument <long?>("index", null); if (!(hash is null ^ index is null)) { throw new GraphQL.ExecutionError( "The parameters hash and index are mutually exclusive; " + "give only one at a time."); } if (hash is string hashNotNull) { return(Query <T> .GetBlockByHash(HashDigest <SHA256> .FromString(hashNotNull))); } if (index is long indexNotNull) { return(Query <T> .GetBlockByIndex(indexNotNull)); } throw new GraphQL.ExecutionError("Unexpected block query"); }
public BlocksQuery(BlockChain <T> chain) { Field <NonNullGraphType <ListGraphType <NonNullGraphType <BlockType <T> > > > >( "blocks", arguments: new QueryArguments( new QueryArgument <BooleanGraphType> { Name = "desc", DefaultValue = false, }, new QueryArgument <IntGraphType> { Name = "offset", DefaultValue = 0, }, new QueryArgument <IntGraphType> { Name = "limit" }, new QueryArgument <BooleanGraphType> { Name = "excludeEmptyTxs", DefaultValue = false, } ), resolve: context => { bool desc = context.GetArgument <bool>("desc"); long offset = context.GetArgument <long>("offset"); int?limit = context.GetArgument <int?>("limit", null); bool excludeEmptyTxs = context.GetArgument <bool>("excludeEmptyTxs"); return(ListBlocks(desc, offset, limit, excludeEmptyTxs)); } ); Field <BlockType <T> >( "block", arguments: new QueryArguments( new QueryArgument <IdGraphType> { Name = "hash" } ), resolve: context => { HashDigest <SHA256> hash = HashDigest <SHA256> .FromString( context.GetArgument <string>("hash")); return(_chain[hash]); } ); Field <NonNullGraphType <ListGraphType <NonNullGraphType <TransactionType <T> > > > >( "transactions", arguments: new QueryArguments( new QueryArgument <AddressType> { Name = "signer", DefaultValue = null, }, new QueryArgument <AddressType> { Name = "involvedAddress", DefaultValue = null, }, new QueryArgument <BooleanGraphType> { Name = "desc", DefaultValue = false, }, new QueryArgument <IntGraphType> { Name = "offset", DefaultValue = 0, }, new QueryArgument <IntGraphType> { Name = "limit" } ), resolve: context => { var signer = context.GetArgument <Address>("signer"); var involved = context.GetArgument <Address>("involvedAddress"); bool desc = context.GetArgument <bool>("desc"); long offset = context.GetArgument <long>("offset"); int?limit = context.GetArgument <int?>("limit", null); return(ListTransactions(signer, involved, desc, offset, limit)); } ); Field <TransactionType <T> >( "transaction", arguments: new QueryArguments( new QueryArgument <IdGraphType> { Name = "id" } ), resolve: context => { var id = new TxId( ByteUtil.ParseHex(context.GetArgument <string>("id")) ); return(_chain.GetTransaction(id)); } ); _chain = chain; Name = "BlockQuery"; }