Smart contract architecture
At its core, a blockchain platform can be viewed as a distributed multi-tenant database that holds the state of all the smart contracts deployed on it. After deployment, each smart contract will have a unique address. The address is used to scope the state and as the identifier for state queries and updates. The methods defined in the smart contract code provides the permission checks and logics for queries and updates.
In aelf, a smart contract essentially has three parts: the interface, the state, and the business logic.
the interface - aelf supports smart contracts coded in multiple languages. Protobuf format is adopted as the cross-language definition of the contract.
the state - the language specific SDK provides some prototypes for the state of different types, after the defination of properties of certain prototype, developers could query and update state database via accessing the properties directly.
the business logic - aelf provides protobuf plugins to generate the smart contract skeleton from the contract’s proto definition. Developers just need to fill the logics for each method by override.
Smart contracts in AElf are spread across the Kernel, the runtime and the SDK. The kernel defines the fundamental components and infrastructure associated with smart contracts. It also defines the abstractions for execution. Smart contract also heavily rely on the runtime modules and the sdk project.
Smart contracts, along with the blockchain’s data, form the heart of a blockchain system. They define through some predefined logic how and according to what rules the state of the blockchain is modified.
A smart contract is a collection of methods that each act upon a particular set of state variables.
Transactions trigger the logic contained in smart contracts. If a user of the blockchain wants to modify some state, he needs to build a transaction that will call a specific method on some contract. When the transaction is included in a block and this block is executed, the modifications will be executed.
Smart contracts are a part of what makes dApps possible. They implement a part of the business layer: the part that gets included in the blockchain.
What follows in this section will give you a general overview of how AElf implements smart contracts. The other sections will walk you through different notions more specifically.
In AElf, Smart Contracts are defined like micro-services. This makes Smart Contracts independent of specific programming languages. This implies, for example, that our Consensus Protocol essentially becomes a service because it is defined through Smart Contract.
As showed in the diagram above, smart contracts functionality is defined within the kernel. The kernel defines the fundamental components and infrastructure associated with establishing smart contracts as a service: * SDK abstracts - high-level entities that provide a hook for smart contract services to interact with the chain. * Execution - high-level primitives defined for execution
Smart contract need to interact with the chain and have access to contextual information. For this AElf defines a bridge and a bridge host. Usually the programming SDK corresponding to the specific language will implement features to communicate with/through the bridge.
One of the major functionalities provided by the bridge is the ability to provide contextual information to the smart contract being executed. Here are a few: the Self field represents the address of the current contract being called. the Sender is the address that sent the transaction that executed the contract, and Origin is the address that signed the transaction. Sometimes Sender and Origin are equal.the OriginTransactionId is the ID of the transaction fetch from transaction pool or generated by the current miner, and TransactionId is the Id of the transaction is executing, which means this transaction could be an inline one.
The bridge also exposes extra functionality: contracts can fire Events, which are in a way similar to logging. contracts can call a method on another contract in a read-only manner. Any state change will not be persisted to the blockchain. Send inline - this actually creates a transaction to call another method. As opposed to calling the changes to the state - if any - will be persisted.
The main point of a smart contract is to read and/or modify state. The language SDK’s implement state helpers and through the bridge’s StateProvider.
Runtime and execution
When a block’s transactions are executed, every transaction will generate a trace. Amongst other things, it contains: the return value of the called method, this can be anything defined in protobuf format and is defined in the service definition. error outputs, if execution encountered a problem. the results from inner calls in InlineTraces field. the Logs field will contain the events launched from the called method.
AElf comes with a native C# SDK that gives smart contract developers the necessary tools to develop smart contracts in C#. It contains helpers to communicate with the bridge. By using the SDK, you can also take advantage of the type infrastructure defined in the library: ContractState: an interface that is implemented by a class that is destined to be containers for the state field. MappedState: a base type that defines collections a key-value mapping, generic subclasses are available to enable multi-key scenarios. SingletonState: this defines non-collection types with a
Any developer or company can develop an sdk and a runtime for a specific language by creating an adapter to communicate with the bridge through gRPC.