C# client library for EOSIO blockchains. The library is based on https://github.com/EOSIO/eosjs and MIT licensed.
Install-Package eos-sharp
Visual Studio 2017+
eos-sharp is now available through nuget https://www.nuget.org/packages/eos-sharp
Install-Package eos-sharp
In order to interact with eos blockchain you need to create a new instance of the Eos class with a EosConfigurator.
Example:
Eoseos=newEos(newEosConfigurator(){HttpEndpoint="https://nodes.eos42.io",//MainnetChainId="aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906",ExpireSeconds=60,SignProvider=newDefaultSignProvider("myprivatekey")});- HttpEndpoint - http or https location of a nodeosd server providing a chain API.
- ChainId - unique ID for the blockchain you're connecting to. If no ChainId is provided it will get from the get_info API call.
- ExpireInSeconds - number of seconds before the transaction will expire. The time is based on the nodeosd's clock. An unexpired transaction that may have had an error is a liability until the expiration is reached, this time should be brief.
- SignProvider - signature implementation to handle available keys and signing transactions. Use the DefaultSignProvider with a privateKey to sign transactions inside the lib.
- GetInfo call
varresult=awaiteos.GetInfo();Returns:
classGetInfoResponse{stringserver_version;stringchain_id;UInt32head_block_num;UInt32last_irreversible_block_num;stringlast_irreversible_block_id;stringhead_block_id;DateTimehead_block_time;stringhead_block_producer;stringvirtual_block_cpu_limit;stringvirtual_block_net_limit;stringblock_cpu_limit;stringblock_net_limit;}- GetAccount call
varresult=awaiteos.GetAccount("myaccountname");Returns:
classGetAccountResponse{stringaccount_name;UInt32head_block_num;DateTimehead_block_time;boolprivileged;DateTimelast_code_update;DateTimecreated;Int64ram_quota;Int64net_weight;Int64cpu_weight;Resourcenet_limit;Resourcecpu_limit;UInt64ram_usage;List<Permission>permissions;RefundRequestrefund_request;SelfDelegatedBandwidthself_delegated_bandwidth;TotalResourcestotal_resources;VoterInfovoter_info;}- GetBlock call
varresult=awaiteos.GetBlock("blockIdOrNumber");Returns:
classGetBlockResponse{DateTimetimestamp;stringproducer;UInt32confirmed;stringprevious;stringtransaction_mroot;stringaction_mroot;UInt32schedule_version;Schedulenew_producers;List<Extension>block_extensions;List<Extension>header_extensions;stringproducer_signature;List<TransactionReceipt>transactions;stringid;UInt32block_num;UInt32ref_block_prefix;}- GetTableRows call
- Json
- Code - accountName of the contract to search for table rows
- Scope - scope text segmenting the table set
- Table - table name
- TableKey - unused so far?
- LowerBound - lower bound for the selected index value
- UpperBound - upper bound for the selected index value
- KeyType - Type of the index choosen, ex: i64
- Limit
- IndexPosition - 1 - primary (first), 2 - secondary index (in order defined by multi_index), 3 - third index, etc
- EncodeType - dec, hex
- Reverse - reverse result order
- ShowPayer - show ram payer
varresult=awaiteos.GetTableRows(newGetTableRowsRequest(){json=true,code="eosio.token",scope="EOS",table="stat"});Returns:
classGetTableRowsResponse{List<object>rowsbool?more}Using generic type
/*JsonProperty helps map the fields from the api*/publicclassStat{publicstringissuer{get;set;}publicstringmax_supply{get;set;}publicstringsupply{get;set;}}varresult=awaitEos.GetTableRows<Stat>(newGetTableRowsRequest(){json=true,code="eosio.token",scope="EOS",table="stat"});Returns:
classGetTableRowsResponse<Stat>{List<Stat>rowsbool?more}- GetTableByScope call
- Code - accountName of the contract to search for tables
- Table - table name to filter
- LowerBound - lower bound of scope, optional
- UpperBound - upper bound of scope, optional
- Limit
- Reverse - reverse result order
varresult=awaiteos.GetTableByScope(newGetTableByScopeRequest(){code="eosio.token",table="accounts"});Returns:
classGetTableByScopeResponse{List<TableByScopeResultRow>rows
string more
}classTableByScopeResultRow{stringcode;stringscope;stringtable;stringpayer;UInt32?count;}- GetActions call
- accountName - accountName to get actions history
- pos - a absolute sequence positon -1 is the end/last action
- offset - the number of actions relative to pos, negative numbers return [pos-offset,pos), positive numbers return [pos,pos+offset)
varresult=awaiteos.GetActions("myaccountname",0,10);Returns:
classGetActionsResponse{List<GlobalAction>actions;UInt32last_irreversible_block;booltime_limit_exceeded_error;}NOTE: using anonymous objects and / or properties as action data is not supported on WEBGL Unity exports Use data as dictionary or strongly typed objects with fields.
varresult=awaiteos.CreateTransaction(newTransaction(){actions=newList<Api.v1.Action>(){newApi.v1.Action(){account="eosio.token",authorization=newList<PermissionLevel>(){newPermissionLevel(){actor="tester112345",permission="active"}},name="transfer",data=new{from="tester112345",to="tester212345",quantity="0.0001 EOS",memo="hello crypto world!"}}}});Data can also be a Dictionary with key as string. The dictionary value can be any object with nested Dictionaries
varresult=awaiteos.CreateTransaction(newTransaction(){actions=newList<Api.v1.Action>(){newApi.v1.Action(){account="eosio.token",authorization=newList<PermissionLevel>(){newPermissionLevel(){actor="tester112345",permission="active"}},name="transfer",data=newDictionary<string,string>(){{"from","tester112345"},{"to","tester212345"},{"quantity","0.0001 EOS"},{"memo","hello crypto world!"}}}}});Returns the transactionId
Is also possible to implement your own ISignProvider to customize how the signatures and key handling is done.
Example:
/// <summary>/// Signature provider implementation that uses a private server to hold keys/// </summary>classSuperSecretSignProvider:ISignProvider{/// <summary>/// Get available public keys from signature provider server/// </summary>/// <returns>List of public keys</returns>publicasyncTask<IEnumerable<string>>GetAvailableKeys(){varresult=awaitHttpHelper.GetJsonAsync<SecretResponse>("https://supersecretserver.com/get_available_keys");returnresult.Keys;}/// <summary>/// Sign bytes using the signature provider server/// </summary>/// <param name="chainId">EOSIO Chain id</param>/// <param name="requiredKeys">required public keys for signing this bytes</param>/// <param name="signBytes">signature bytes</param>/// <param name="abiNames">abi contract names to get abi information from</param>/// <returns>List of signatures per required keys</returns>publicasyncTask<IEnumerable<string>>Sign(stringchainId,List<string>requiredKeys,byte[]signBytes){varresult=awaitHttpHelper.PostJsonAsync<SecretSignResponse>("https://supersecretserver.com/sign",newSecretRequest{chainId=chainId,RequiredKeys=requiredKeys,Data=signBytes});returnresult.Signatures;}}// create new Eos client instance using your custom signature providerEoseos=newEos(newEosConfigurator(){SignProvider=newSuperSecretSignProvider(),HttpEndpoint="https://nodes.eos42.io",//MainnetChainId="aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906"});Is also possible to combine multiple signature providers to complete all the signatures for a transaction
Example:
Eoseos=newEos(newEosConfigurator(){HttpEndpoint="https://nodes.eos42.io",//MainnetChainId="aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906",ExpireSeconds=60,SignProvider=newCombinedSignersProvider(newList<ISignProvider>(){newSuperSecretSignProvider(),newDefaultSignProvider("myprivatekey")}),});