Refactor (#7)

* Increment nonce when submitting transaction.

* Refactor.

* use default values from metadata
* use functions from metadata

* Nonce fixup

* Add docs.

* Add contracts module.

* Add set_code.

* Add events to metadata.

* Support pretty printing metadata.

* Add subscriptions.

* Add submit_and_watch to XtBuilder.

* nits from review
This commit is contained in:
David Craven
2019-08-12 17:07:28 +02:00
committed by GitHub
parent be5ccc1d11
commit 151c7f7e0a
9 changed files with 888 additions and 267 deletions
+146
View File
@@ -0,0 +1,146 @@
//! Implements support for the srml_contracts module.
use crate::{
codec::compact,
error::Error,
srml::{
balances::Balances,
system::System,
},
XtBuilder,
};
use futures::future::{
self,
Future,
};
use parity_scale_codec::Codec;
use runtime_primitives::traits::StaticLookup;
use substrate_primitives::Pair;
/// Gas units are chosen to be represented by u64 so that gas metering
/// instructions can operate on them efficiently.
pub type Gas = u64;
/// The subset of the `srml_contracts::Trait` that a client must implement.
pub trait Contracts: System + Balances {}
/// The Contracts extension trait for the XtBuilder.
pub trait ContractsCall {
/// Contracts type.
type Contracts: Contracts;
/// Stores the given binary Wasm code into the chain's storage and returns
/// its `codehash`.
/// You can instantiate contracts only with stored code.
fn put_code(
&mut self,
gas_limit: Gas,
code: Vec<u8>,
) -> Box<dyn Future<Item = <Self::Contracts as System>::Hash, Error = Error> + Send>;
/// Creates a new contract from the `codehash` generated by `put_code`,
/// optionally transferring some balance.
///
/// Creation is executed as follows:
///
/// - The destination address is computed based on the sender and hash of
/// the code.
/// - The smart-contract account is created at the computed address.
/// - The `ctor_code` is executed in the context of the newly-created
/// account. Buffer returned after the execution is saved as the `code`
/// of the account. That code will be invoked upon any call received by
/// this account.
/// - The contract is initialized.
fn create(
&mut self,
endowment: <Self::Contracts as Balances>::Balance,
gas_limit: Gas,
code_hash: <Self::Contracts as System>::Hash,
data: Vec<u8>,
) -> Box<dyn Future<Item = <Self::Contracts as System>::Hash, Error = Error> + Send>;
/// Makes a call to an account, optionally transferring some balance.
///
/// * If the account is a smart-contract account, the associated code will
/// be executed and any value will be transferred.
/// * If the account is a regular account, any value will be transferred.
/// * If no account exists and the call value is not less than
/// `existential_deposit`, a regular account will be created and any value
/// will be transferred.
fn call(
&mut self,
dest: <<Self::Contracts as System>::Lookup as StaticLookup>::Source,
value: <Self::Contracts as Balances>::Balance,
gas_limit: Gas,
data: Vec<u8>,
) -> Box<dyn Future<Item = <Self::Contracts as System>::Hash, Error = Error> + Send>;
}
impl<T: Contracts + 'static, P> ContractsCall for XtBuilder<T, P>
where
P: Pair,
P::Public: Into<<<T as System>::Lookup as StaticLookup>::Source>,
P::Signature: Codec,
{
type Contracts = T;
fn put_code(
&mut self,
gas_limit: Gas,
code: Vec<u8>,
) -> Box<dyn Future<Item = <Self::Contracts as System>::Hash, Error = Error> + Send>
{
let put_code_call = || {
Ok(self
.metadata()
.module("Contracts")?
.call("put_code", (compact(gas_limit), code))?)
};
let call = match put_code_call() {
Ok(call) => call,
Err(err) => return Box::new(future::err(err)),
};
Box::new(self.submit(call))
}
fn create(
&mut self,
endowment: <Self::Contracts as Balances>::Balance,
gas_limit: Gas,
code_hash: <Self::Contracts as System>::Hash,
data: Vec<u8>,
) -> Box<dyn Future<Item = <Self::Contracts as System>::Hash, Error = Error> + Send>
{
let create_call = || {
Ok(self.metadata().module("Contracts")?.call(
"create",
(compact(endowment), compact(gas_limit), code_hash, data),
)?)
};
let call = match create_call() {
Ok(call) => call,
Err(err) => return Box::new(future::err(err)),
};
Box::new(self.submit(call))
}
fn call(
&mut self,
dest: <<Self::Contracts as System>::Lookup as StaticLookup>::Source,
value: <Self::Contracts as Balances>::Balance,
gas_limit: Gas,
data: Vec<u8>,
) -> Box<dyn Future<Item = <Self::Contracts as System>::Hash, Error = Error> + Send>
{
let call_call = || {
Ok(self
.metadata()
.module("Contracts")?
.call("call", (dest, compact(value), compact(gas_limit), data))?)
};
let call = match call_call() {
Ok(call) => call,
Err(err) => return Box::new(future::err(err)),
};
Box::new(self.submit(call))
}
}