Blockchain Module4
Blockchain Module4
1
Creating Contracts
contract OwnedToken {
// `TokenCreator` is a contract type that is defined below. It is fine to reference it
// as long as it is not used to create a new contract.
TokenCreator creator;
address owner;
bytes32 name;
// This is the constructor which registers the creator and the assigned name.
constructor(bytes32 _name) {
// State variables are accessed via their name and not via e.g. `this.owner`. Functions can be
// accessed directly or through `this.f`, but the latter provides an external view to the function.
// In constructor, you should not access functions externally, because the function does not exist yet.
owner = msg.sender;
// We perform an explicit type conversion from `address` to `TokenCreator` and assume that the type of
// calling contract is `TokenCreator`, there is no real way to verify that.
creator = TokenCreator(msg.sender);
name = _name;
}
2
Creating Contracts
function transfer(address newOwner) public {
// Only the current owner can transfer the token.
if (msg.sender != owner) return;
// We ask the creator contract if the transfer should proceed. If the call fails the execution also fails here.
if (creator.isTokenTransferOK(owner, newOwner))
owner = newOwner;
}
}
contract TokenCreator {
function createToken(bytes32 name) public returns (OwnedToken tokenAddress) {
// Create a new `Token` contract and return its address. From the JavaScript side, the return type of this function is
// `address`, as this is closest type available in the ABI.
return new OwnedToken(name);
}
// Perform checks to determine if transferring a token to the `OwnedToken` contract should proceed
function isTokenTransferOK(address currentOwner, address newOwner)
public pure returns (bool ok) {
// Check an arbitrary condition to see if transfer should proceed
return keccak256(abi.encodePacked(currentOwner, newOwner))[0] == 0x7f;
}
}
3
Getter Functions
1. The compiler automatically creates getter functions for all public state variables. State
variables can be initialized when they are declared.
contract C { uint public data = 42; }
contract Caller {
C c = new C();
function f() public view returns (uint) { return c.data(); }
}
2. The getter functions have external visibility. If symbol is accessed internally (without this), it
evaluates to a state variable. If it is accessed externally (with this), it evaluates to a function.
contract C { uint public data;
function x() public returns (uint) {
data = 3; // internal access
return this.data(); // external access
}
}
3. If you have a public state variable of array type, then you can only retrieve single elements of
the array via the generated getter function. This mechanism exists to avoid high gas costs
when returning an entire array.
4. If you want to return an entire array in one call, then you need to write a function.
4
Function Modifiers
1. Modifiers can be used to change the behaviour of functions in a declarative way.
You can use a modifier to automatically check a condition prior to executing the
function.
2. Modifiers are inheritable properties of contracts and may be overridden by derived
contracts, but only if they are marked virtual.
3. Multiple modifiers are applied to a function by specifying them in a whitespace-
separated list and are evaluated in the order presented.
4. Explicit returns from a modifier or function body only leave the current modifier or
function body.
5. Arbitrary expressions are allowed for modifier arguments and in this context, all
symbols visible from the function are visible in the modifier.
6. Symbols introduced in the modifier are not visible in the function.
7. The function body is inserted where the special symbol "_;" appears in the
definition of a modifier. Thus, if condition of modifier is satisfied while calling this
function, the function is executed and otherwise, an exception is thrown.
5
Function Modifiers
contract Owner {
address owner;
constructor() public { owner = msg.sender; }
modifier onlyOwner {
require(msg.sender == owner);
_;
}
modifier costs(uint price) {
if (msg.value >= price) {
_;
}
}
}
7
Constant & Immutable State Variables
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.7.2;
contract C {
string constant TEXT = "abc";
bytes32 constant MY_HASH = keccak256("abc");
uint immutable decimals;
uint immutable maxBalance;
address immutable Functions
owner = msg.sender;
contract ArrayExample {
bool found;
function f(uint[] memory _arr) public {
// This calls the free function internally. The compiler will add its code to the contract.
uint s = sum(_arr);
require(s >= 10);
found = true;
}
}
3. Functions take typed parameters as input and unlike in many other languages, may also
return an arbitrary number of values as output.
4. Function parameters are declared the same way as variables and the name of unused
parameters can be omitted.