Created
July 3, 2018 17:01
-
-
Save glitch003/916b54bb71ef15231af3d64c3c5de97b 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.4.24+commit.e67f0147.js&optimize=false&gist=
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.16; | |
/** | |
* @title BytesToTypes | |
* @dev The BytesToTypes contract converts the memory byte arrays to the standard solidity types | |
* @author pouladzade@gmail.com | |
*/ | |
contract BytesToTypes { | |
function bytesToAddress(uint _offst, bytes memory _input) internal pure returns (address _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToBool(uint _offst, bytes memory _input) internal pure returns (bool _output) { | |
uint8 x; | |
assembly { | |
x := mload(add(_input, _offst)) | |
} | |
x==0 ? _output = false : _output = true; | |
} | |
function getStringSize(uint _offst, bytes memory _input) internal pure returns(uint size){ | |
assembly{ | |
size := mload(add(_input,_offst)) | |
let chunk_count := add(div(size,32),1) // chunk_count = size/32 + 1 | |
if gt(mod(size,32),0) {// if size%32 > 0 | |
chunk_count := add(chunk_count,1) | |
} | |
size := mul(chunk_count,32)// first 32 bytes reseves for size in strings | |
} | |
} | |
function bytesToString(uint _offst, bytes memory _input, bytes memory _output) internal { | |
uint size = 32; | |
assembly { | |
let loop_index:= 0 | |
let chunk_count | |
size := mload(add(_input,_offst)) | |
chunk_count := add(div(size,32),1) // chunk_count = size/32 + 1 | |
if gt(mod(size,32),0) { | |
chunk_count := add(chunk_count,1) // chunk_count++ | |
} | |
loop: | |
mstore(add(_output,mul(loop_index,32)),mload(add(_input,_offst))) | |
_offst := sub(_offst,32) // _offst -= 32 | |
loop_index := add(loop_index,1) | |
jumpi(loop , lt(loop_index , chunk_count)) | |
} | |
} | |
function bytesToBytes32(uint _offst, bytes memory _input, bytes32 _output) internal pure { | |
assembly { | |
mstore(_output , add(_input, _offst)) | |
mstore(add(_output,32) , add(add(_input, _offst),32)) | |
} | |
} | |
function bytesToInt8(uint _offst, bytes memory _input) internal pure returns (int8 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt16(uint _offst, bytes memory _input) internal pure returns (int16 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt24(uint _offst, bytes memory _input) internal pure returns (int24 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt32(uint _offst, bytes memory _input) internal pure returns (int32 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt40(uint _offst, bytes memory _input) internal pure returns (int40 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt48(uint _offst, bytes memory _input) internal pure returns (int48 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt56(uint _offst, bytes memory _input) internal pure returns (int56 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt64(uint _offst, bytes memory _input) internal pure returns (int64 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt72(uint _offst, bytes memory _input) internal pure returns (int72 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt80(uint _offst, bytes memory _input) internal pure returns (int80 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt88(uint _offst, bytes memory _input) internal pure returns (int88 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt96(uint _offst, bytes memory _input) internal pure returns (int96 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt104(uint _offst, bytes memory _input) internal pure returns (int104 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt112(uint _offst, bytes memory _input) internal pure returns (int112 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt120(uint _offst, bytes memory _input) internal pure returns (int120 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt128(uint _offst, bytes memory _input) internal pure returns (int128 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt136(uint _offst, bytes memory _input) internal pure returns (int136 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt144(uint _offst, bytes memory _input) internal pure returns (int144 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt152(uint _offst, bytes memory _input) internal pure returns (int152 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt160(uint _offst, bytes memory _input) internal pure returns (int160 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt168(uint _offst, bytes memory _input) internal pure returns (int168 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt176(uint _offst, bytes memory _input) internal pure returns (int176 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt184(uint _offst, bytes memory _input) internal pure returns (int184 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt192(uint _offst, bytes memory _input) internal pure returns (int192 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt200(uint _offst, bytes memory _input) internal pure returns (int200 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt208(uint _offst, bytes memory _input) internal pure returns (int208 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt216(uint _offst, bytes memory _input) internal pure returns (int216 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt224(uint _offst, bytes memory _input) internal pure returns (int224 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt232(uint _offst, bytes memory _input) internal pure returns (int232 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt240(uint _offst, bytes memory _input) internal pure returns (int240 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt248(uint _offst, bytes memory _input) internal pure returns (int248 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToInt256(uint _offst, bytes memory _input) internal pure returns (int256 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint8(uint _offst, bytes memory _input) internal pure returns (uint8 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint16(uint _offst, bytes memory _input) internal pure returns (uint16 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint24(uint _offst, bytes memory _input) internal pure returns (uint24 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint32(uint _offst, bytes memory _input) internal pure returns (uint32 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint40(uint _offst, bytes memory _input) internal pure returns (uint40 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint48(uint _offst, bytes memory _input) internal pure returns (uint48 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint56(uint _offst, bytes memory _input) internal pure returns (uint56 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint64(uint _offst, bytes memory _input) internal pure returns (uint64 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint72(uint _offst, bytes memory _input) internal pure returns (uint72 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint80(uint _offst, bytes memory _input) internal pure returns (uint80 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint88(uint _offst, bytes memory _input) internal pure returns (uint88 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint96(uint _offst, bytes memory _input) internal pure returns (uint96 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint104(uint _offst, bytes memory _input) internal pure returns (uint104 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint112(uint _offst, bytes memory _input) internal pure returns (uint112 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint120(uint _offst, bytes memory _input) internal pure returns (uint120 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint128(uint _offst, bytes memory _input) internal pure returns (uint128 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint136(uint _offst, bytes memory _input) internal pure returns (uint136 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint144(uint _offst, bytes memory _input) internal pure returns (uint144 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint152(uint _offst, bytes memory _input) internal pure returns (uint152 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint160(uint _offst, bytes memory _input) internal pure returns (uint160 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint168(uint _offst, bytes memory _input) internal pure returns (uint168 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint176(uint _offst, bytes memory _input) internal pure returns (uint176 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint184(uint _offst, bytes memory _input) internal pure returns (uint184 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint192(uint _offst, bytes memory _input) internal pure returns (uint192 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint200(uint _offst, bytes memory _input) internal pure returns (uint200 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint208(uint _offst, bytes memory _input) internal pure returns (uint208 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint216(uint _offst, bytes memory _input) internal pure returns (uint216 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint224(uint _offst, bytes memory _input) internal pure returns (uint224 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint232(uint _offst, bytes memory _input) internal pure returns (uint232 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint240(uint _offst, bytes memory _input) internal pure returns (uint240 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint248(uint _offst, bytes memory _input) internal pure returns (uint248 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
function bytesToUint256(uint _offst, bytes memory _input) internal pure returns (uint256 _output) { | |
assembly { | |
_output := mload(add(_input, _offst)) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.24; | |
import "./SafeMath.sol"; | |
import "./Seriality.sol"; | |
contract Distribute is Seriality { | |
using SafeMath for uint; | |
struct Payee { | |
uint8 weight; | |
address delegate; | |
} | |
struct InternalPayee { | |
uint8 weight; | |
bytes32 entityNameHash; | |
} | |
struct Entity { | |
Payee[] payees; | |
InternalPayee[] internalPayees; | |
uint weightSum; | |
string projectName; | |
uint unclaimedBalance; | |
} | |
event Payout( | |
address indexed payee, | |
bytes32 indexed projectHash, | |
uint totalAmount, | |
uint amount, | |
uint8 payeeWeight, | |
uint weightSum | |
); | |
event InternalPayout( | |
bytes32 indexed payee, | |
bytes32 indexed projectHash, | |
uint totalAmount, | |
uint amount, | |
uint8 payeeWeight, | |
uint weightSum | |
); | |
event LogSerializedThings( | |
bytes logged | |
); | |
event LogProjectName( | |
bytes32 projectName | |
); | |
event UnclaimedFundsDeposited( | |
bytes32 projectName, | |
uint amount | |
); | |
mapping(bytes32 => Entity) entities; | |
constructor() public { | |
} | |
// this function tests serializing a project with 3 "external" payees, meaning eth gets sent out of the contract | |
// this functions also tests adding 2 "internal" payees, meaning eth stays in the contract but is saved as belonging to those entities, and they may claim it | |
function testSerializingToString() public { | |
bytes32 projectName = 0xe4ac8a6219f8a92127b1d83627c4dbf8dc4d72b701905f389e27a36c614bb1c4; | |
// we actually need (20+1)*3 + 12 = 75 bytes | |
// we have to allocate 63 bytes + 12 extra bytes = 75 bytes because each uint is 32 bytes and we need space to copy those zeroes of the uint8 (the other 31 bytes are zeroes) | |
bytes memory buffer = new bytes(75); | |
uint offset = 75; | |
uintToBytes(offset, 10, buffer); | |
offset -= 1; | |
addressToBytes(offset, 0x50e2dac5e78B5905CB09495547452cEE64426db2, buffer); | |
offset -= 20; | |
uintToBytes(offset, 60, buffer); | |
offset -= 1; | |
addressToBytes(offset, 0xFff175c14A299Ef7027Da0d348F438E154880CCD, buffer); | |
offset -= 20; | |
uintToBytes(offset, 5, buffer); | |
offset -= 1; | |
addressToBytes(offset, 0xa3d471B11cc47d6CdAd87587641B9b2D6E4a217E, buffer); | |
// emit LogSerializedThings(buffer); | |
// we need 65 bytes per entry, because each hash uses 64 and the uint8 uses 1 and we have 2 entries so 130 total. | |
// NOTE each hash should really be 32 bytes. i mean, it's a 256 bit hash. 256 / 8 = 32 bytes. why is it taking up 64 bytes though? am i misunderstanding something? | |
bytes memory internalPayeeBuffer = new bytes(130); | |
offset = 130; | |
uintToBytes(offset, 10, internalPayeeBuffer); | |
offset -= 33; | |
// emit LogSerializedThings(internalPayeeBuffer); | |
bytes32ToBytes(offset, keccak256("glitch003"), internalPayeeBuffer); | |
offset -= 32; | |
// emit LogSerializedThings(internalPayeeBuffer); | |
uintToBytes(offset, 15, internalPayeeBuffer); | |
// emit LogSerializedThings(internalPayeeBuffer); | |
offset -= 33; | |
bytes32ToBytes(offset, keccak256("webpack/webpack"), internalPayeeBuffer); | |
// emit LogSerializedThings(internalPayeeBuffer); | |
setAllPayees(projectName, buffer, internalPayeeBuffer); | |
} | |
function setAllPayees(bytes32 entityName, bytes serializedPayees, bytes serializedInternalPayees) public { | |
// bytesToBytes32(uint _offst, bytes memory _input, bytes32 _output) | |
// bytes32 entityName = betterBytesToBytes32(serializedParameters, offset); | |
// bytesToBytes32(32, serializedParameters, entityName); | |
emit LogProjectName(entityName); | |
Entity storage entity = entities[entityName]; | |
entity.payees.length = 0; // truncate array | |
entity.internalPayees.length = 0; // truncate array | |
entity.weightSum = 0; // reset weight sum | |
uint offset = serializedPayees.length; | |
// loop over each entry of regular payees | |
// length of each entry is 1 byte for uint8 weight + 20 bytes for address delegate = 21 bytes | |
// we must also subtract 12 for the extra padding | |
uint entries = (serializedPayees.length - 12) / 21; | |
for(uint i = 0; i < entries; i++){ | |
uint8 weight = bytesToUint8(offset, serializedPayees); | |
offset -= 1; | |
address delegate = bytesToAddress(offset, serializedPayees); | |
offset -= 20; | |
Payee memory newPayee = Payee(weight, delegate); | |
entity.payees.push(newPayee); | |
entity.weightSum += weight; | |
} | |
offset = serializedInternalPayees.length; | |
// loop over each entry of internal payees | |
// length of each entry is 1 byte for uint8 weight + 64 bytes for entity name hash = 65 bytes | |
entries = serializedInternalPayees.length / 65; | |
for(i = 0; i < entries; i++){ | |
weight = bytesToUint8(offset, serializedInternalPayees); | |
offset -= 1; | |
bytes32 internalEntityName = betterBytesToBytes32(serializedInternalPayees, offset - 64); | |
offset -= 64; | |
InternalPayee memory newInternalPayee = InternalPayee(weight, internalEntityName); | |
entity.internalPayees.push(newInternalPayee); | |
entity.weightSum += weight; | |
} | |
} | |
// send eth to an entity, and it will be stored for them to claim it | |
// if it has been claimed, send the eth to wherever the claimer asked | |
function sendEthToEntity(bytes32 entityName) public payable { | |
Entity storage entity = entities[entityName]; | |
Payee[] storage payees = entity.payees; | |
InternalPayee[] storage internalPayees = entity.internalPayees; | |
// check if this entity is unclaimed because there is nobody to pay | |
if (payees.length == 0) { | |
entity.unclaimedBalance += msg.value; | |
emit UnclaimedFundsDeposited(entityName, msg.value); | |
return; | |
} | |
// entity is claimed | |
// check if there is a unclaimed balance on it, and if so, roll it up to send with the rest of msg.value | |
uint totalPayable = msg.value; | |
if (entity.unclaimedBalance != 0) { | |
totalPayable += entity.unclaimedBalance; | |
entity.unclaimedBalance = 0; | |
} | |
uint weightSum = entity.weightSum; | |
// send eth to payees | |
for (uint i = 0; i < payees.length; i++){ | |
Payee storage payee = payees[i]; | |
uint payout = totalPayable.mul(payee.weight).div(weightSum); | |
payee.delegate.transfer(payout); | |
emit Payout(payee.delegate, entityName, totalPayable, payout, payee.weight, weightSum); | |
} | |
// send eth to internal payees where they can claim it | |
for (i = 0; i < internalPayees.length; i++){ | |
InternalPayee storage internalPayee = internalPayees[i]; | |
payout = totalPayable.mul(internalPayee.weight).div(weightSum); | |
Entity storage internalPayeeEntity = entities[internalPayee.entityNameHash]; | |
internalPayeeEntity.unclaimedBalance += payout; | |
emit InternalPayout(internalPayee.entityNameHash, entityName, totalPayable, payout, payee.weight, weightSum); | |
} | |
} | |
// test funcs | |
function testItOnce() payable public { | |
addPayee(0xe4ac8a6219f8a92127b1d83627c4dbf8dc4d72b701905f389e27a36c614bb1c4, 10, 0x50e2dac5e78B5905CB09495547452cEE64426db2); | |
addPayee(0xe4ac8a6219f8a92127b1d83627c4dbf8dc4d72b701905f389e27a36c614bb1c4, 90, 0xFff175c14A299Ef7027Da0d348F438E154880CCD); | |
sendEthToEntity(0xe4ac8a6219f8a92127b1d83627c4dbf8dc4d72b701905f389e27a36c614bb1c4); | |
} | |
function testItAgain() payable public { | |
sendEthToEntity(0xe4ac8a6219f8a92127b1d83627c4dbf8dc4d72b701905f389e27a36c614bb1c4); | |
} | |
// util funcs for payee | |
function addPayee(bytes32 entityName, uint8 weight, address delegate) public { | |
Entity storage entity = entities[entityName]; | |
Payee memory newPayee = Payee(weight, delegate); | |
entity.payees.push(newPayee); | |
entity.weightSum += weight; | |
} | |
function getEntityPayeesLength(bytes32 entityName) view public returns (uint) { | |
return entities[entityName].payees.length; | |
} | |
function getEntityPayeeAtIndex(bytes32 entityName, uint index) view public returns (uint,address) { | |
Payee storage thePayee = entities[entityName].payees[index]; | |
return (thePayee.weight, thePayee.delegate); | |
} | |
function removeEntityPayeeAtIndex(bytes32 entityName, uint index) public { | |
Entity storage entity = entities[entityName]; | |
uint weightToRemove = entity.payees[index].weight; | |
entity.weightSum -= weightToRemove; | |
for (uint i = index; i<entity.payees.length-1; i++){ | |
entity.payees[i] = entity.payees[i+1]; | |
} | |
entity.payees.length--; | |
} | |
// util funcs for internalPayee | |
function addInternalPayee(bytes32 entityName, uint8 weight, bytes32 internalEntityName) public { | |
Entity storage entity = entities[entityName]; | |
InternalPayee memory newPayee = InternalPayee(weight, internalEntityName); | |
entity.internalPayees.push(newPayee); | |
entity.weightSum += weight; | |
} | |
function getEntityInternalPayeesLength(bytes32 entityName) view public returns (uint) { | |
return entities[entityName].internalPayees.length; | |
} | |
function getEntityInternalPayeeAtIndex(bytes32 entityName, uint index) view public returns (uint,bytes32) { | |
InternalPayee storage thePayee = entities[entityName].internalPayees[index]; | |
return (thePayee.weight, thePayee.entityNameHash); | |
} | |
function removeEntityInternalPayeeAtIndex(bytes32 entityName, uint index) public { | |
Entity storage entity = entities[entityName]; | |
uint weightToRemove = entity.internalPayees[index].weight; | |
entity.weightSum -= weightToRemove; | |
for (uint i = index; i<entity.internalPayees.length-1; i++){ | |
entity.internalPayees[i] = entity.internalPayees[i+1]; | |
} | |
entity.internalPayees.length--; | |
} | |
// the bytesToBytes32 inside Seriality doesn't work. This one does, but confusingly, writes forwards (left to right) but seriality writes backwards (right to left) | |
// i also think this one is gas-inefficient and will switch to an assembly version of this eventually | |
function betterBytesToBytes32(bytes b, uint offset) private pure returns (bytes32) { | |
bytes32 out; | |
for (uint i = 0; i < 32; i++) { | |
out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); | |
} | |
return out; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.24; | |
/** | |
* @title SafeMath | |
* @dev Math operations with safety checks that throw on error | |
*/ | |
library SafeMath { | |
/** | |
* @dev Multiplies two numbers, throws on overflow. | |
*/ | |
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { | |
// Gas optimization: this is cheaper than asserting 'a' not being zero, but the | |
// benefit is lost if 'b' is also tested. | |
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 | |
if (a == 0) { | |
return 0; | |
} | |
c = a * b; | |
assert(c / a == b); | |
return c; | |
} | |
/** | |
* @dev Integer division of two numbers, truncating the quotient. | |
*/ | |
function div(uint256 a, uint256 b) internal pure returns (uint256) { | |
// assert(b > 0); // Solidity automatically throws when dividing by 0 | |
// uint256 c = a / b; | |
// assert(a == b * c + a % b); // There is no case in which this doesn't hold | |
return a / b; | |
} | |
/** | |
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). | |
*/ | |
function sub(uint256 a, uint256 b) internal pure returns (uint256) { | |
assert(b <= a); | |
return a - b; | |
} | |
/** | |
* @dev Adds two numbers, throws on overflow. | |
*/ | |
function add(uint256 a, uint256 b) internal pure returns (uint256 c) { | |
c = a + b; | |
assert(c >= a); | |
return c; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.16; | |
/** | |
* @title Seriality | |
* @dev The Seriality contract is the main interface for serializing data using the TypeToBytes, BytesToType and SizeOf | |
* @author pouladzade@gmail.com | |
*/ | |
import "./BytesToTypes.sol"; | |
import "./TypesToBytes.sol"; | |
import "./SizeOf.sol"; | |
contract Seriality is BytesToTypes, TypesToBytes, SizeOf { | |
function Seriality() public { | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.16; | |
/** | |
* @title SizeOf | |
* @dev The SizeOf return the size of the solidity types in byte | |
* @author pouladzade@gmail.com | |
*/ | |
contract SizeOf { | |
function sizeOfString(string _in) internal pure returns(uint _size){ | |
_size = bytes(_in).length / 32; | |
if(bytes(_in).length % 32 != 0) | |
_size++; | |
_size++; // first 32 bytes is reserved for the size of the string | |
_size *= 32; | |
} | |
function sizeOfInt(uint16 _postfix) internal pure returns(uint size){ | |
assembly{ | |
switch _postfix | |
case 8 { size := 1 } | |
case 16 { size := 2 } | |
case 24 { size := 3 } | |
case 32 { size := 4 } | |
case 40 { size := 5 } | |
case 48 { size := 6 } | |
case 56 { size := 7 } | |
case 64 { size := 8 } | |
case 72 { size := 9 } | |
case 80 { size := 10 } | |
case 88 { size := 11 } | |
case 96 { size := 12 } | |
case 104 { size := 13 } | |
case 112 { size := 14 } | |
case 120 { size := 15 } | |
case 128 { size := 16 } | |
case 136 { size := 17 } | |
case 144 { size := 18 } | |
case 152 { size := 19 } | |
case 160 { size := 20 } | |
case 168 { size := 21 } | |
case 176 { size := 22 } | |
case 184 { size := 23 } | |
case 192 { size := 24 } | |
case 200 { size := 25 } | |
case 208 { size := 26 } | |
case 216 { size := 27 } | |
case 224 { size := 28 } | |
case 232 { size := 29 } | |
case 240 { size := 30 } | |
case 248 { size := 31 } | |
case 256 { size := 32 } | |
default { size := 32 } | |
} | |
} | |
function sizeOfUint(uint16 _postfix) internal pure returns(uint size){ | |
return sizeOfInt(_postfix); | |
} | |
function sizeOfAddress() internal pure returns(uint8){ | |
return 20; | |
} | |
function sizeOfBool() internal pure returns(uint8){ | |
return 1; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.16; | |
/** | |
* @title TypesToBytes | |
* @dev The TypesToBytes contract converts the standard solidity types to the byte array | |
* @author pouladzade@gmail.com | |
*/ | |
contract TypesToBytes { | |
function TypesToBytes() internal { | |
} | |
function addressToBytes(uint _offst, address _input, bytes memory _output) internal pure { | |
assembly { | |
mstore(add(_output, _offst), _input) | |
} | |
} | |
function bytes32ToBytes(uint _offst, bytes32 _input, bytes memory _output) internal pure { | |
assembly { | |
mstore(add(_output, _offst), _input) | |
mstore(add(add(_output, _offst),32), add(_input,32)) | |
} | |
} | |
function boolToBytes(uint _offst, bool _input, bytes memory _output) internal pure { | |
uint8 x = _input == false ? 0 : 1; | |
assembly { | |
mstore(add(_output, _offst), x) | |
} | |
} | |
function stringToBytes(uint _offst, bytes memory _input, bytes memory _output) internal { | |
uint256 stack_size = _input.length / 32; | |
if(_input.length % 32 > 0) stack_size++; | |
assembly { | |
let index := 0 | |
stack_size := add(stack_size,1)//adding because of 32 first bytes memory as the length | |
loop: | |
mstore(add(_output, _offst), mload(add(_input,mul(index,32)))) | |
_offst := sub(_offst , 32) | |
index := add(index ,1) | |
jumpi(loop , lt(index,stack_size)) | |
} | |
} | |
function intToBytes(uint _offst, int _input, bytes memory _output) internal pure { | |
assembly { | |
mstore(add(_output, _offst), _input) | |
} | |
} | |
function uintToBytes(uint _offst, uint _input, bytes memory _output) internal pure { | |
assembly { | |
mstore(add(_output, _offst), _input) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment