Blockchain Engineering: Solidity Tutorials -Role-6.
Interfacing with other Contracts
contract OwnedToken // TokenCreator is a contract type that is defined below. It is fine to reference it // every bit long as it is non used to create a new contract. TokenCreator creator; address owner; bytes32 advert; office OwnedToken(bytes32 _name) address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2; nameReg.call("register", _name); owner = msg.sender; // We do an explicit type conversion from `address` to `TokenCreator` and assume that the type of // the calling contract is TokenCreator, there is no real way to check. creator = TokenCreator(msg.sender); name = _name; office changeName(bytes32 newName) // Only the creator can alter the name -- contracts are explicitly convertible to addresses. if (msg.sender == address(creator)) name = newName; office transfer(address newOwner) // Only the current owner can transfer the token. if (msg.sender != owner) return; // We also want to ask the creator if the transfer is fine. // Note that this calls a function of the contract defined below. // If the call fails (e.g. due to out-of-gas), the execution here stops // immediately (the ability to catch this will be added later). if (creator.isTokenTransferOK(owner, newOwner)) owner = newOwner; contract TokenCreator role createToken(bytes32 refer) returns (address tokenAddress) // Create a new Token contract and return its address. return address(new OwnedToken(name)); function changeName(address tokenAddress, bytes32 bring up) // We need an explicit type conversion because contract types are not part of the ABI. OwnedToken token = OwnedToken(tokenAddress); token.changeName(name); function isTokenTransferOK(address currentOwner, address newOwner) returns (bool ok) // Check some arbitrary condition. address tokenAddress = msg.sender; return (sha3(newOwner) & 0xff) == (bytes20(tokenAddress) & 0xff);
contract owned office owned() owner = msg.sender; address owner; // Use "is" to derive from some other contract. Derived contracts can access all members // including individual functions and storage variables. contract soul is owned part kill() if (msg.sender == owner) suicide(owner); // These are solely provided to make the interface known to the compiler. contract Config office lookup(uint id) returns (address adr) contract NameReg function register(bytes32 advert) function unregister() // Multiple inheritance is possible. Note that "owned" is as well a base of operations form of // "soul", all the same in that location is only a single example of "owned" (equally for virtual // inheritance in C++). contract named is owned, individual function named(bytes32 bring up) address ConfigAddress = 0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970; NameReg(Config(ConfigAddress).lookup(1)).register(name); // Functions tin be overridden, both local too message-based part calls have // these overrides into business relationship. role kill() if (msg.sender == possessor) address ConfigAddress = 0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970; NameReg(Config(ConfigAddress).lookup(1)).unregister(); // It is still possible to call a specific overridden function. mortal.kill(); // If a constructor takes an argument, it needs to live provided in the header. contract PriceFeed is owned, soul, named("GoldFeed") function updateInfo(uint newInfo) if (msg.sender == owner) info = newInfo; office get() constant returns(uint r) return info; uint info;
contract mortal is owned part kill() if (msg.sender == owner) suicide(owner); contract Base1 is soul role kill() /* do cleanup 1 */ mortal.kill(); contract Base2 is individual role kill() /* do cleanup 2 */ mortal.kill(); contract Final is Base1, Base2
contract someone is owned function kill() if (msg.sender == owner) suicide(owner); contract Base1 is person office kill() /* do cleanup 1 */ super.kill(); contract Base2 is person part kill() /* do cleanup 2 */ super.kill(); contract Final is Base1, Base2
Multiple Inheritance as well as Linearization
contract X contract A is X contract C is A, X
contract feline function utterance() returns (bytes32);
contract Cat is feline office utterance() returns (bytes32) return "miaow";
contract c office f(uint a) private returns (uint b) return a + 1; office setData(uint a) inherited data = a; uint public data;
contract exam uint public data = 42;
contract complex struct Data uint a; bytes3 b; mapping(uint => uint) map; mapping(uint => mapping(bool => Data)) public data;
part information(uint arg1, bool arg2, uint arg3) returns (uint a, bytes3 b) a = data[arg1][arg2][arg3].a; b = data[arg1][arg2][arg3].b;
contract Test function() x = 1; uint x; contract Caller part callTest(address testAddress) Test(testAddress).send(0); // results in Test(testAddress).x becoming == 1.
contract owned function owned() owner = msg.sender; address owner; // This contract only defines a modifier but does not use it - it will // be used in derived contracts. // The function body is inserted where the special symbol "_" in the // definition of a modifier appears. modifier onlyowner if (msg.sender == owner) _ contract mortal is owned // This contract inherits the "onlyowner"-modifier from "owned" and // applies it to the "kill"-function, which causes that calls to "kill" // only have an effect if they are made by the stored owner. function kill() onlyowner suicide(owner); contract priced // Modifiers can receive arguments: modifier costs(uint price) if (msg.value >= price) _ contract Register is priced, owned mapping (address => bool) registeredAddresses; uint cost; role Register(uint initialPrice) price = initialPrice; part register() costs(cost) registeredAddresses[msg.sender] = true; part changePrice(uint _price) onlyowner price = _price;