Skip to content

Instantly share code, notes, and snippets.

@mwmwmw
Last active January 12, 2022 07:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mwmwmw/682c4181919671031e53cef7268a866e to your computer and use it in GitHub Desktop.
Save mwmwmw/682c4181919671031e53cef7268a866e 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.8.7+commit.e28d00a7.js&optimize=false&runs=200&gist=
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title Base64
/// @author Brecht Devos - <brecht@loopring.org>
/// @notice Provides functions for encoding/decoding base64
library Base64 {
string internal constant TABLE_ENCODE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
bytes internal constant TABLE_DECODE = hex"0000000000000000000000000000000000000000000000000000000000000000"
hex"00000000000000000000003e0000003f3435363738393a3b3c3d000000000000"
hex"00000102030405060708090a0b0c0d0e0f101112131415161718190000000000"
hex"001a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132330000000000";
function encode(bytes memory data) internal pure returns (string memory) {
if (data.length == 0) return '';
// load the table into memory
string memory table = TABLE_ENCODE;
// multiply by 4/3 rounded up
uint256 encodedLen = 4 * ((data.length + 2) / 3);
// add some extra buffer at the end required for the writing
string memory result = new string(encodedLen + 32);
assembly {
// set the actual output length
mstore(result, encodedLen)
// prepare the lookup table
let tablePtr := add(table, 1)
// input ptr
let dataPtr := data
let endPtr := add(dataPtr, mload(data))
// result ptr, jump over length
let resultPtr := add(result, 32)
// run over the input, 3 bytes at a time
for {} lt(dataPtr, endPtr) {}
{
// read 3 bytes
dataPtr := add(dataPtr, 3)
let input := mload(dataPtr)
// write 4 characters
mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
resultPtr := add(resultPtr, 1)
mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
resultPtr := add(resultPtr, 1)
mstore8(resultPtr, mload(add(tablePtr, and(shr( 6, input), 0x3F))))
resultPtr := add(resultPtr, 1)
mstore8(resultPtr, mload(add(tablePtr, and( input, 0x3F))))
resultPtr := add(resultPtr, 1)
}
// padding with '='
switch mod(mload(data), 3)
case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }
case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }
}
return result;
}
function decode(string memory _data) internal pure returns (bytes memory) {
bytes memory data = bytes(_data);
if (data.length == 0) return new bytes(0);
require(data.length % 4 == 0, "invalid base64 decoder input");
// load the table into memory
bytes memory table = TABLE_DECODE;
// every 4 characters represent 3 bytes
uint256 decodedLen = (data.length / 4) * 3;
// add some extra buffer at the end required for the writing
bytes memory result = new bytes(decodedLen + 32);
assembly {
// padding with '='
let lastBytes := mload(add(data, mload(data)))
if eq(and(lastBytes, 0xFF), 0x3d) {
decodedLen := sub(decodedLen, 1)
if eq(and(lastBytes, 0xFFFF), 0x3d3d) {
decodedLen := sub(decodedLen, 1)
}
}
// set the actual output length
mstore(result, decodedLen)
// prepare the lookup table
let tablePtr := add(table, 1)
// input ptr
let dataPtr := data
let endPtr := add(dataPtr, mload(data))
// result ptr, jump over length
let resultPtr := add(result, 32)
// run over the input, 4 characters at a time
for {} lt(dataPtr, endPtr) {}
{
// read 4 characters
dataPtr := add(dataPtr, 4)
let input := mload(dataPtr)
// write 3 bytes
let output := add(
add(
shl(18, and(mload(add(tablePtr, and(shr(24, input), 0xFF))), 0xFF)),
shl(12, and(mload(add(tablePtr, and(shr(16, input), 0xFF))), 0xFF))),
add(
shl( 6, and(mload(add(tablePtr, and(shr( 8, input), 0xFF))), 0xFF)),
and(mload(add(tablePtr, and( input , 0xFF))), 0xFF)
)
)
mstore(resultPtr, shl(232, output))
resultPtr := add(resultPtr, 3)
}
}
return result;
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
import "./Base64.sol";
struct Game {
address p1;
address p2;
string result;
}
// GAS COST 1 = 176749
// GAS COST 2 = 96377
// GAS COST 3 = 133765 ????
contract RPS {
uint256 public gameCount;
mapping(uint256 => Game) public games;
function toString(address account) public pure returns(string memory) {
return toString(abi.encodePacked(account));
}
function toString(bytes memory data) public pure returns(string memory) {
bytes memory alphabet = "0123456789abcdef";
bytes memory str = new bytes(2 + data.length * 2);
str[0] = "0";
str[1] = "x";
for (uint i = 0; i < data.length; i++) {
str[2+i*2] = alphabet[uint(uint8(data[i] >> 4))];
str[3+i*2] = alphabet[uint(uint8(data[i] & 0x0f))];
}
return string(str);
}
function Play(address player1, address player2) public returns(string memory) {
Game memory game;
game.p1 = player1;
game.p2 = player2;
uint256 p1fate = uint256(
keccak256(
abi.encodePacked(
gameCount,
player1,
block.difficulty,
block.timestamp
)
)
)%3;
uint256 p2fate = uint256(
keccak256(
abi.encodePacked(
gameCount,
player2,
block.difficulty,
block.timestamp
)
)
)%3;
if(p1fate == 0 && p2fate == 2 || p1fate == 1 && p2fate == 0 || p1fate == 2 && p2fate == 1) {
game.result = "Player 1 Wins";
}
if(p2fate == 0 && p1fate == 2 || p2fate == 1 && p1fate == 0 || p2fate == 2 && p1fate == 1) {
game.result = "Player 2 Wins";
}
if(p2fate == 0 && p1fate == 0 || p2fate == 1 && p1fate == 1 || p2fate == 2 && p1fate == 2) {
game.result = "Draw";
}
games[gameCount++] = game;
return string(abi.encodePacked(
'{"player1":"',
toString(game.p1),
'","player2":"',
toString(game.p2),
'","result":"',
game.result,
'"}'
));
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
import "./Base64.sol";
struct Game {
address p1;
address p2;
uint256 p1fate;
uint256 p2fate;
}
contract RPS {
uint256 public gameCount;
mapping(uint256 => Game) public games;
function toString(address account) public pure returns(string memory) {
return toString(abi.encodePacked(account));
}
function toString(bytes memory data) public pure returns(string memory) {
bytes memory alphabet = "0123456789abcdef";
bytes memory str = new bytes(2 + data.length * 2);
str[0] = "0";
str[1] = "x";
for (uint i = 0; i < data.length; i++) {
str[2+i*2] = alphabet[uint(uint8(data[i] >> 4))];
str[3+i*2] = alphabet[uint(uint8(data[i] & 0x0f))];
}
return string(str);
}
function Play(address player1, address player2) public {
Game memory game;
game.p1 = player1;
game.p2 = player2;
game.p1fate = uint256(
keccak256(
abi.encodePacked(
gameCount,
player1,
block.difficulty,
block.timestamp
)
)
)%3;
game.p2fate = uint256(
keccak256(
abi.encodePacked(
gameCount,
player2,
block.difficulty,
block.timestamp
)
)
)%3;
games[gameCount++] = game;
}
function getGame(uint256 gameId) public view returns (string memory) {
Game memory game = games[gameId];
string memory result;
if(game.p1fate == 0 && game.p2fate == 2 || game.p1fate == 1 && game.p2fate == 0 || game.p1fate == 2 && game.p2fate == 1) {
result = "Player 1 Wins";
}
if(game.p2fate == 0 && game.p1fate == 2 || game.p2fate == 1 && game.p1fate == 0 || game.p2fate == 2 && game.p1fate == 1) {
result = "Player 2 Wins";
}
if(game.p2fate == 0 && game.p1fate == 0 || game.p2fate == 1 && game.p1fate == 1 || game.p2fate == 2 && game.p1fate == 2) {
result = "Draw";
}
return string(abi.encodePacked(
'{"player1":"',
toString(game.p1),
'","player2":"',
toString(game.p2),
'","result":"',
result,
'"}'
));
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
import "./Base64.sol";
struct Game {
address p1;
address p2;
uint256 seed1;
uint256 seed2;
}
contract RPS {
uint256 public gameCount;
mapping(uint256 => Game) public games;
function toString(address account) public pure returns(string memory) {
return toString(abi.encodePacked(account));
}
function toString(bytes memory data) public pure returns(string memory) {
bytes memory alphabet = "0123456789abcdef";
bytes memory str = new bytes(2 + data.length * 2);
str[0] = "0";
str[1] = "x";
for (uint i = 0; i < data.length; i++) {
str[2+i*2] = alphabet[uint(uint8(data[i] >> 4))];
str[3+i*2] = alphabet[uint(uint8(data[i] & 0x0f))];
}
return string(str);
}
function Play(address player1, address player2) public {
Game memory game;
game.p1 = player1;
game.p2 = player2;
game.seed1 = block.difficulty;
game.seed2 = block.timestamp;
games[gameCount++] = game;
}
function getGame(uint256 gameId) public view returns (string memory) {
Game memory game = games[gameId];
uint256 p1fate = uint256(
keccak256(
abi.encodePacked(
gameId,
game.p1,
game.seed1,
game.seed2
)
)
)%3;
uint256 p2fate = uint256(
keccak256(
abi.encodePacked(
gameId,
game.p2,
game.seed1,
game.seed2
)
)
)%3;
string memory result;
if(p1fate == 0 && p2fate == 2 || p1fate == 1 && p2fate == 0 || p1fate == 2 && p2fate == 1) {
result = "Player 1 Wins";
}
if(p2fate == 0 && p1fate == 2 || p2fate == 1 && p1fate == 0 || p2fate == 2 && p1fate == 1) {
result = "Player 2 Wins";
}
if(p2fate == 0 && p1fate == 0 || p2fate == 1 && p1fate == 1 || p2fate == 2 && p1fate == 2) {
result = "Draw";
}
return string(abi.encodePacked(
'{"player1":"',
toString(game.p1),
'","player2":"',
toString(game.p2),
'","result":"',
result,
'"}'
));
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
import "./Base64.sol";
contract Simple {
string myValue;
function setValue(string memory a, string memory b) public {
myValue = string(abi.encodePacked(a, " ", b));
}
function getValue() public view returns (string memory) {
return myValue;
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
import "./Base64.sol";
contract Simple {
string myValue;
// 49370 gas
function setValue(string memory a, string memory b) public {
myValue = Base64.encode(abi.encodePacked(a, " ", b));
}
function getValue() public view returns (string memory) {
return myValue;
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
import "./Base64.sol";
contract Simple {
bytes myValue;
// 47174 gas
function setValue(string memory a, string memory b) public {
myValue = abi.encodePacked(a, " ", b);
}
function getValue() public view returns (string memory) {
return Base64.encode(myValue);
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
import "./Base64.sol";
contract Simple {
string myValue1;
string myValue2;
// 68687 gas
function setValue(string memory a, string memory b) public {
myValue1 = a;
myValue2 = b;
}
function getValue() public view returns (string memory) {
return Base64.encode(abi.encodePacked(myValue1, " ", myValue2));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment