Skip to content

Instantly share code, notes, and snippets.

@lyhistory
Created February 22, 2019 10:23
Show Gist options
  • Save lyhistory/2976c80aa8772c257df76d936104852e to your computer and use it in GitHub Desktop.
Save lyhistory/2976c80aa8772c257df76d936104852e to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.5.1+commit.c8a2cb62.js&optimize=false&gist=
pragma solidity ^0.5.0;
contract A {
uint public a;
//A constructor set asinternalcauses the contract to be marked asabstract
constructor(uint _a) internal {
a = _a;
}
}
contract B is A(1) {
constructor() public {}
}
contract Base {
uint x;
constructor(uint _x) public { x = _x; }
}
// Either directly specify in the inheritance list...
contract Derived1 is Base(7) {
constructor() public {}
}
// or through a "modifier" of the derived constructor
contract Derived2 is Base {
constructor(uint _y) Base(_y *_y) public {}
}
pragma solidity >=0.4.22 <0.6.0;
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) public {
// 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. Especially in the constructor,
// you should not access functions externally,
// because the function does not exist yet.
// See the next section for details.
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 that.
creator = TokenCreator(msg.sender);
name = _name;
}
function changeName(bytes32 newName) public {
// Only the creator can alter the name --
// the comparison is possible since contracts
// are explicitly convertible to addresses.
if(msg.sender == address(creator))
name = newName;
}
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 by using a function of the
// `TokenCreator` contract defined below. If
// the call fails (e.g. due to out-of-gas),
// 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 is
// `address`, as this is the closest type available in
// the ABI.
return new OwnedToken(name);
}
function changeName(OwnedToken tokenAddress, bytes32 name) public{
// Again, the external type of `tokenAddress` is
// simply `address`.
tokenAddress.changeName(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;
}
}
pragma solidity ^0.5.0;
contract Test {
// This function is called for all messages sent to
// this contract (there is no other function).
// Sending Ether to this contract will cause an exception,
// because the fallback function does not have the `payable`
// modifier.
function() external payable {
//x = 1; //send and transfer will fail because only 2300gas forwarded to prevent
}
uint x;
function getX() public view returns(uint){
return x;
}
function getBalance() public view returns(uint){
return address(this).balance;
}
}
// This contract keeps all Ether sent to it with no way
// to get it back.
contract Sink {
function() external payable {}
}
contract Caller {
function callTest(Test test) public returns(bool) {
(bool success, ) = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));
//require(success);
// results in test.x becoming == 1.
// address(test) will not allow to call ``send`` directly, since ``test`` has no payable
// fallback function. It has to be converted to the ``address payable`` type via an
// intermediate conversion to ``uint160`` to even allow calling ``send`` on it.
address payable testPayable = address(uint160(address(test)));
// If someone sends ether to that contract,
// the transfer will fail, i.e. this returns false here.
return address(test).send(2 ether);//testPayable.send(2 ether);
}
function() external payable {}
function getBalance() public view returns(uint){
return address(this).balance;
}
}
pragma solidity ^0.5.0;
contract owned {
constructor() public{ owner = msg.sender; }
address payable 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.
// This means that if the owner calls this function, the
// function is executed and otherwise, an exception is
// thrown.
modifier onlyOwner {
require(
msg.sender == owner,
"Only owner can call this function."
);
_;
}
}
contract mortal is owned {
// This contract inherits the `onlyOwner` modifier from
// `owned` and applies it to the `close` function, which
// causes that calls to `close` only have an effect if
// they are made by the stored owner.
function close() public onlyOwner {
selfdestruct(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 price;
constructor(uint initialPrice) public {price=initialPrice;}
// It is important to also provide the
// `payable` keyword here, otherwise the function will
// automatically reject all Ether sent to it.
function register() public payable costs(price) {
registeredAddresses[msg.sender] = true;
}
function changePrice(uint _price) public onlyOwner {
price = _price;
}
}
contract Mutex {
bool locked;
modifier noReentrancy() {
require(
!locked,
"Reentrant call."
);
locked = true;
_;
locked = false;
}
/// This function is protected by a mutex, which means that
/// reentrant calls from within `msg.sender.call` cannot call `f` again.
/// The `return 7` statement assigns 7 to the return value but still
/// executes the statement `locked = false` in the modifier.
function f() public noReentrancy returns(uint){
(bool success,) = msg.sender.call("");
require(success);
return 7;
}
}
pragma solidity >=0.4.16 <0.6.0;
contract A {
function f(uint _in) public pure returns(uint out){
out = _in;
}
function f(uint _in, bool _really) public pure returns(uint out){
if(_really)
out = _in;
}
}
pragma solidity ^0.5.0;
contract owned {
constructor() public payable { owner = msg.sender; }
address payable owner;
}
// Use `is` to derive from another contract. Derived
// contracts can access all non-private members including
// internal functions and state variables. These cannot be
// accessed externally via `this`, though.
contract mortal is owned {
function kill() public {
if(msg.sender == owner) selfdestruct(owner);
}
}
// These abstract contracts are only provided to make the
// interface known to the compiler. Note the function
// without body. If a contract does not implement all
// functions it can only be used as an interface.
contract Config {
function lookup(uint id) public returns (address adr);
}
contract NameReg {
function register(bytes32 name) public;
function unregister() public;
}
contract MyConfig is Config {
mapping(uint=>address) lookupmap;
function lookup(uint id) public returns (address adr){
return lookupmap[id];
}
function add(uint id, address addr) public{
lookupmap[id] = addr;
}
}
contract MyNameReg is NameReg {
mapping(address=>bytes32) regmap;
function register(bytes32 name) public{
regmap[msg.sender] = name;
}
function unregister() public{
delete regmap[msg.sender];
}
}
// Multiple inheritance is possible. Note that `owned` is
// also a base class of `mortal`, yet there is only a single
// instance of `owned` (as for virtual inheritance in C++).
contract named is owned, mortal {
constructor(bytes32 name) public payable{
Config config = Config(0x01E7eCe729eAbb35C11aEa36780A3c7898A694C4);
NameReg(config.lookup(1)).register(name);
}
// Functions can be overridden by another function with the same name and
// the same number/types of inputs. If the overriding function has different
// types of output parameters, that causes an error.
// Both local and message-based function calls take these overrides
// into account.
function kill() public {
if(msg.sender == owner) {
Config config = Config(0x01E7eCe729eAbb35C11aEa36780A3c7898A694C4);
NameReg(config.lookup(1)).unregister();
// It is still possible to call a specific
// overridden function.
mortal.kill();
}
}
}
// If a constructor takes an argument, it needs to be
// provided in the header (or modifier-invocation-style at
// the constructor of the derived contract (see below)).
contract PriceFeed is owned, mortal, named("GoldFeed") {
function updateInfo(uint newInfo) public {
if(msg.sender == owner) info = newInfo;
}
function get() public view returns(uint r) { return info; }
uint info;
}
pragma solidity >=0.4.22 <0.6.0;
contract owned {
constructor() public { owner = msg.sender; }
address payable owner;
}
contract mortal is owned {
function kill() public {
if(msg.sender == owner) selfdestruct(owner);
}
}
contract Base1 is mortal {
function kill() public { /* do cleanup 1 */ super.kill(); }
}
contract Base2 is mortal {
function kill() public { /* do cleanup 2 */ super.kill(); }
}
contract Final is Base1, Base2 {
//IfBase2calls a function ofsuper, it does not simply call this function on one of its base contracts.
//Rather, it callsthis function on the next base contract in the final inheritance graph,
//so it will callBase1.kill()(note that the finalinheritance sequence is –
//starting with the most derived contract: Final, Base2, Base1, mortal, owned).
//The actualfunction that is called when using super is not known in the context of the class where it is used,
//although its type isknown. This is similar for ordinary virtual method lookup.
}
pragma solidity >=0.4.22 <0.6.0;
library Set {
// We define a new struct datatype that will be used to
// hold its data in the calling contract.
struct Data { mapping(uint => bool) flags; }
// Note that the first parameter is of type "storage
// reference" and thus only its storage address and not
// its contents is passed as part of the call. This is a
// special feature of library functions. It is idiomatic
// to call the first parameter `self`, if the function can
// be seen as a method of that object.
function insert(Data storage self, uint value) public returns(bool) {
if(self.flags[value])
return false; //already there
self.flags[value] = true;
return true;
}
function remove(Data storage self, uint value) public returns(bool){
if(!self.flags[value])
return false; //not there
self.flags[value] = false;
return true;
}
function contains(Data storage self, uint value) public view returns(bool){
return self.flags[value];
}
}
contract C {
Set.Data knownValues;
// In this contract, we can also directly access knownValues.flags, if we want.
function register(uint value) public {
// The library functions can be called without a
// specific instance of the library, since the
// "instance" will be the current contract.
require(Set.insert(knownValues, value));
}
function checkRegister(uint value) public returns(bool){
return knownValues.flags[value];
}
}
pragma solidity >=0.4.16 <0.6.0;
library BigInt {
struct bigint {
uint[] limbs;
}
function fromUint(uint x) internal pure returns(bigint memory r) {
r.limbs = new uint[](1);
r.limbs[0] = x;
}
function limb(bigint memory _a, uint _limb) internal pure returns(uint){
return _limb < _a.limbs.length ? _a.limbs[_limb] : 0;
}
function max(uint a, uint b) private pure returns(uint){
return a > b ? a : b;
}
function add(bigint memory _a, bigint memory _b) internal pure returns(bigint memory r){
r.limbs = new uint[](max(_a.limbs.length, _b.limbs.length));
uint carry = 0;
for(uint i=0; i<r.limbs.length; ++i) {
uint a = limb(_a, i);
uint b = limb(_b, i);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment