diff --git a/substrate/srml/contract/src/lib.rs b/substrate/srml/contract/src/lib.rs
index 63b425eba4..6fbd502f01 100644
--- a/substrate/srml/contract/src/lib.rs
+++ b/substrate/srml/contract/src/lib.rs
@@ -14,41 +14,71 @@
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see .
-//! Smart-contract module for runtime; Allows deployment and execution of smart-contracts
-//! expressed in WebAssembly.
+//! # Contract Module
+//!
+//! The contract module provides functionality for the runtime to deploy and execute WebAssembly smart-contracts.
+//! The supported dispatchable functions are documented as part of the [`Call`](./enum.Call.html) enum.
+//!
+//! ## Overview
+//!
+//! This module extends accounts (see `Balances` module) to have smart-contract functionality.
+//! These "smart-contract accounts" have the ability to create smart-contracts and make calls to other contract
+//! and non-contract accounts.
+//!
+//! The smart-contract code is stored once in a `code_cache`, and later retrievable via its `code_hash`.
+//! This means that multiple smart-contracts can be instantiated from the same `code_cache`, without replicating
+//! the code each time.
+//!
+//! When a smart-contract is called, its associated code is retrieved via the code hash and gets executed.
+//! This call can alter the storage entries of the smart-contract account, create new smart-contracts,
+//! or call other smart-contracts.
+//!
+//! Finally, when the `Balances` module determines an account is dead (i.e. account balance fell below the
+//! existential deposit), it reaps the account. This will delete the associated code and storage of the
+//! smart-contract account.
+//!
+//! ### Gas
+//!
+//! Senders must specify a gas limit with every call, as all instructions invoked by the smart-contract require gas.
+//! Unused gas is refunded after the call, regardless of the execution outcome.
+//!
+//! If the gas limit is reached, then all calls and state changes (including balance transfers) are only
+//! reverted at the current call's contract level. For example, if contract A calls B and B runs out of gas mid-call,
+//! then all of B's calls are reverted. Assuming correct error handling by contract A, A's other calls and state
+//! changes still persist.
+//!
+//! ### Notable Scenarios
+//!
+//! Contract call failures are not always cascading. When failures occur in a sub-call, they do not "bubble up",
+//! and the call will only revert at the specific contract level. For example, if contract A calls contract B, and B
+//! fails, A can decide how to handle that failure, either proceeding or reverting A's changes.
+//!
+//! ## Interface
+//!
+//! ### Dispatchable functions
+//!
+//! * `put_code` - Stores the given binary Wasm code into the chains storage and returns its `code_hash`.
+//!
+//! * `create` - Deploys a new contract from the given `code_hash`, optionally transferring some balance.
+//! This creates a new smart contract account and calls its contract deploy handler to initialize the contract.
+//!
+//! * `call` - Makes a call to an account, optionally transferring some balance.
//!
-//! This module provides an ability to create smart-contract accounts and send them messages.
-//! A smart-contract is an account with associated code and storage. When such an account receives a message,
-//! the code associated with that account gets executed.
-//!
-//! The code is allowed to alter the storage entries of the associated account,
-//! create smart-contracts or send messages to existing smart-contracts.
-//!
-//! For any actions invoked by the smart-contracts fee must be paid. The fee is paid in gas.
-//! Gas is bought upfront up to the, specified in transaction, limit. Any unused gas is refunded
-//! after the transaction (regardless of the execution outcome). If all gas is used,
-//! then changes made for the specific call or create are reverted (including balance transfers).
-//!
-//! Failures are typically not cascading. That, for example, means that if contract A calls B and B errors
-//! somehow, then A can decide if it should proceed or error.
-//!
-//! # Interaction with the system
-//!
-//! ## Finalization
-//!
-//! This module requires performing some finalization steps at the end of the block. If not performed
-//! the module will have incorrect behavior.
-//!
-//! Thus [`Module::on_finalise`] must be called at the end of the block. The order in relation to
-//! the other module doesn't matter.
-//!
-//! ## Account killing
-//!
-//! When `staking` module determines that account is dead (e.g. account's balance fell below
-//! exsistential deposit) then it reaps the account. That will lead to deletion of the associated
-//! code and storage of the account.
-//!
-//! [`Module::on_finalise`]: struct.Module.html#impl-OnFinalise
+//! ### Public functions
+//!
+//! See the [module](./struct.Module.html) for details on publicly available functions.
+//!
+//! ## Usage
+//!
+//! The contract module is a work in progress. The following examples show how this contract module can be
+//! used to create and call contracts.
+//!
+//! * [`pDSL`](https://github.com/Robbepop/pdsl) is a domain specific language which enables writing
+//! WebAssembly based smart contracts in the Rust programming language. This is a work in progress.
+//!
+//! ## Related Modules
+//! * [`Balances`](https://crates.parity.io/srml_balances/index.html)
+//!
#![cfg_attr(not(feature = "std"), no_std)]
@@ -218,7 +248,8 @@ decl_module! {
Ok(())
}
- /// Stores code in the storage. You can instantiate contracts only with stored code.
+ /// Stores the given binary Wasm code into the chains storage and returns its `codehash`.
+ /// You can instantiate contracts only with stored code.
fn put_code(
origin,
#[compact] gas_limit: T::Gas,
@@ -239,7 +270,13 @@ decl_module! {
result.map(|_| ())
}
- /// Make a call to a specified account, optionally transferring some balance.
+ /// 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(
origin,
dest: ::Source,
@@ -286,15 +323,16 @@ decl_module! {
result.map(|_| ())
}
- /// Create a new contract, optionally transferring some balance to the created account.
+ /// 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.
- /// - account is created at the computed address.
+ /// - 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 message received by this account.
+ /// upon any call received by this account.
+ /// - The contract is initialized.
fn create(
origin,
#[compact] endowment: BalanceOf,
@@ -304,7 +342,7 @@ decl_module! {
) -> Result {
let origin = ensure_signed(origin)?;
- // Pay for the gas upfront.
+ // Commit the gas upfront.
//
// NOTE: it is very important to avoid any state changes before
// paying for the gas.
@@ -352,7 +390,7 @@ decl_event! {
::AccountId,
::Hash
{
- /// Transfer happened `from` -> `to` with given `value` as part of a `message-call` or `create`.
+ /// Transfer happened `from` to `to` with given `value` as part of a `call` or `create`.
Transfer(AccountId, AccountId, Balance),
/// Contract deployed by address at the specified address.
@@ -380,11 +418,11 @@ decl_storage! {
TransactionBaseFee get(transaction_base_fee) config(): BalanceOf;
/// The fee to be paid for making a transaction; the per-byte portion.
TransactionByteFee get(transaction_byte_fee) config(): BalanceOf;
- /// The fee required to create a contract.
+ /// The fee required to create a contract instance.
ContractFee get(contract_fee) config(): BalanceOf = BalanceOf::::sa(21);
- /// The fee charged for a call into a contract.
+ /// The base fee charged for calling into a contract.
CallBaseFee get(call_base_fee) config(): T::Gas = T::Gas::sa(135);
- /// The fee charged for a create of a contract.
+ /// The base fee charged for creating a contract.
CreateBaseFee get(create_base_fee) config(): T::Gas = T::Gas::sa(175);
/// The price of one unit of gas.
GasPrice get(gas_price) config(): BalanceOf = BalanceOf::::sa(1);
diff --git a/substrate/srml/contract/src/tests.rs b/substrate/srml/contract/src/tests.rs
index 36b98098b0..1c18329bf2 100644
--- a/substrate/srml/contract/src/tests.rs
+++ b/substrate/srml/contract/src/tests.rs
@@ -243,7 +243,7 @@ fn account_removal_removes_storage() {
with_externalities(
&mut ExtBuilder::default().existential_deposit(100).build(),
|| {
- // Setup two accounts with free balance above than exsistential threshold.
+ // Set up two accounts with free balance above the existential threshold.
{
Balances::deposit_creating(&1, 110);
AccountInfoOf::::insert(1, &AccountInfo {
@@ -264,7 +264,7 @@ fn account_removal_removes_storage() {
}
// Transfer funds from account 1 of such amount that after this transfer
- // the balance of account 1 is will be below than exsistential threshold.
+ // the balance of account 1 will be below the existential threshold.
//
// This should lead to the removal of all storage associated with this account.
assert_ok!(Balances::transfer(Origin::signed(1), 2, 20));