Skip to content

Instantly share code, notes, and snippets.

@heglex
Last active January 16, 2018 22:33
Show Gist options
  • Save heglex/de5cb5c4078a4bb8eb0b7107846ee56b to your computer and use it in GitHub Desktop.
Save heglex/de5cb5c4078a4bb8eb0b7107846ee56b to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# note--you need to install pysha3, and not the native library,\n",
"# which doesn't include keccak_256\n",
"import sha3"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# These examples are from Tx 0xa7b0ac87684771f6d6204a09b5a0bf0b97f6adf61b78138e8fd264828e36b956\n",
"\n",
"# matron.genes\n",
"arg1 = 0x000063169218f348dc640d171b000208934b5a90189038cb3084624a50f7316c\n",
"\n",
"# sire.genes\n",
"arg2 = 0x00005a13429085339c6521ef0300011c82438c628cc431a63298e3721f772d29\n",
"\n",
"# matron.cooldownEndBlock - 1\n",
"arg3 = 0x000000000000000000000000000000000000000000000000000000000047ff27\n",
"\n",
"# BLOCKHASH of block number equal to arg3\n",
"blockhash = 0xf9dd4486d68b13839d2f7b345f5223f17abae39a951f2cea5b0ca0dd6dc8db83"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# load arguments into bytes arrays in big-Endian order\n",
"\n",
"args1 = []\n",
"for cnt in range(32):\n",
" args1.append(arg1//((1<<8)**cnt)&0xff)\n",
"args1.reverse()\n",
"args1 = bytes(args1)\n",
"\n",
"args2 = []\n",
"for cnt in range(32):\n",
" args2.append(arg2//((1<<8)**cnt)&0xff)\n",
"args2.reverse()\n",
"args2 = bytes(args2)\n",
"\n",
"\n",
"args3 = []\n",
"for cnt in range(32):\n",
" args3.append(arg3//((1<<8)**cnt)&0xff)\n",
"args3.reverse()\n",
"args3 = bytes(args3)\n",
"\n",
"blockhashes = []\n",
"for cnt in range(32):\n",
" blockhashes.append(blockhash//((1<<8)**cnt)&0xff)\n",
"blockhashes.reverse()\n",
"blockhashes = bytes(blockhashes)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# concatenate bytes arrays\n",
"\n",
"alls = blockhashes + args1 + args2 + args3"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0xe30dd999bfba6dd6cd4540fb58c5a1c117e6938c0931459b1c9f6e01d865c19e\n"
]
}
],
"source": [
"# get hash of bytes arrays. This is your source of \"randomness\"\n",
"\n",
"hash = sha3.keccak_256(alls)\n",
"hash = int.from_bytes(hash.digest(), byteorder = 'big')\n",
"\n",
"print(hex(hash))"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# get 5-bit chunks of matron and sire\n",
"\n",
"def masker(arg, start, numbytes):\n",
" mask = 2**numbytes - 1\n",
" mask = mask << start\n",
" out = arg & mask\n",
" out = out >> start\n",
" \n",
" return out\n",
"\n",
"arg1masks = []\n",
"for cnt in range(0x30):\n",
" arg1masks.append(masker(arg1, 5*cnt, 5))\n",
" \n",
"arg2masks = []\n",
"for cnt in range(0x30):\n",
" arg2masks.append(masker(arg2, 5*cnt, 5))\n",
" \n",
"arg1maskscopy = arg1masks.copy()\n",
"arg2maskscopy = arg2masks.copy()"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# note in worst case hashindex wont reach 256 so no need for modulo\n",
"hashindex = 0\n",
"\n",
"# swap dominant/recessive genes according to masked_hash\n",
"for bigcounter in range(0x0c):\n",
" for smallcounter in range(3, 0, -1):\n",
" count = 4*bigcounter + smallcounter\n",
" \n",
" masked_hash = masker(hash, hashindex, 2)\n",
" hashindex += 2\n",
" if masked_hash == 0:\n",
" tmp = arg1maskscopy[count - 1]\n",
" arg1maskscopy[count - 1] = arg1maskscopy[count]\n",
" arg1maskscopy[count] = tmp\n",
" \n",
" masked_hash = masker(hash, hashindex, 2)\n",
" hashindex += 2\n",
" if masked_hash == 0:\n",
" tmp = arg2maskscopy[count - 1]\n",
" arg2maskscopy[count - 1] = arg2maskscopy[count]\n",
" arg2maskscopy[count] = tmp\n",
"\n",
"# combine genes from swapped parent genes, introducing mutations\n",
"outmasks = []\n",
"for cnt in range(0x30):\n",
" rando_byte = 0\n",
" \n",
" # mutate only on dominant genes\n",
" if cnt%4 == 0:\n",
" tmp1 = arg1maskscopy[cnt]&1\n",
" tmp2 = arg2maskscopy[cnt]&1\n",
"\n",
" if tmp1 != tmp2:\n",
" masked_hash = masker(hash, hashindex, 3)\n",
" hashindex += 3\n",
" \n",
" mask1 = arg1maskscopy[cnt]\n",
" mask2 = arg2maskscopy[cnt]\n",
" \n",
" # mutate only if the two parent dominant genes differ by 1...\n",
" if abs(mask2 - mask1) == 1:\n",
" min_mask = min(mask1, mask2)\n",
" # and the smaller of the two is even...\n",
" if min_mask % 2 == 0:\n",
" if min_mask < 0x17:\n",
" trial = masked_hash > 1\n",
" else:\n",
" trial = masked_hash > 0\n",
" if not trial:\n",
" # mutation is the smaller of the two parent dominant genes,\n",
" # divided by two, plus 16\n",
" rando_byte = (min_mask >> 1) + 0x10\n",
" \n",
" if rando_byte > 0:\n",
" print(cnt)\n",
" outmasks.append(rando_byte)\n",
" continue\n",
" \n",
" masked_hash = masker(hash, hashindex, 1)\n",
" hashindex += 1\n",
" \n",
" if masked_hash == 0:\n",
" outmasks.append(arg1maskscopy[cnt])\n",
" else:\n",
" outmasks.append(arg2maskscopy[cnt])\n",
" \n",
" "
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0x5b174298a44b9c6521176000021c53734c9018c431a73298674a5177316c\n",
"0x5b174298a44b9c6521176000021c53734c9018c431a73298674a5177316c\n"
]
}
],
"source": [
"# this is where we will accumulate the calculated child genes\n",
"outs = 0\n",
"\n",
"# this is where you can put the known child genes, for testing\n",
"outs2 = 0x5b174298a44b9c6521176000021c53734c9018c431a73298674a5177316c\n",
"\n",
"for cnt in range(0x30):\n",
" outs |= outmasks[cnt] << 5*cnt\n",
"\n",
"# print both for comparison\n",
"print(hex(outs))\n",
"print(hex(outs2))"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 0xc 0xc\n",
"1 0xb 0xb\n",
"2 0xc 0xc\n",
"3 0xe 0xe\n",
"4 0x17 0x17\n",
"5 0x8 0x8\n",
"6 0x9 0x9\n",
"7 0x9 0x9\n",
"8 0x7 0x7\n",
"9 0x3 0x3\n",
"10 0x6 0x6\n",
"11 0x5 0x5\n",
"12 0x13 0x13\n",
"13 0x13 0x13\n",
"14 0x6 0x6\n",
"15 0x6 0x6\n",
"16 0x4 0x4\n",
"17 0x6 0x6\n",
"18 0x6 0x6\n",
"19 0x0 0x0\n",
"20 0x9 0x9\n",
"21 0x6 0x6\n",
"22 0xd 0xd\n",
"23 0xe 0xe\n",
"24 0x13 0x13\n",
"25 0x2 0x2\n",
"26 0x7 0x7\n",
"27 0x4 0x4\n",
"28 0x0 0x0\n",
"29 0x0 0x0\n",
"30 0x0 0x0\n",
"31 0xc 0xc\n",
"32 0x17 0x17\n",
"33 0x8 0x8\n",
"34 0x8 0x8\n",
"35 0xa 0xa\n",
"36 0x6 0x6\n",
"37 0xe 0xe\n",
"38 0xe 0xe\n",
"39 0x9 0x9\n",
"40 0x4 0x4\n",
"41 0x5 0x5\n",
"42 0x6 0x6\n",
"43 0x5 0x5\n",
"44 0x14 0x14\n",
"45 0xb 0xb\n",
"46 0xc 0xc\n",
"47 0xb 0xb\n"
]
}
],
"source": [
"# or, separately print each 5-bit gene\n",
"for cnt, outmask in enumerate(outmasks):\n",
" print(cnt, hex(outmask), hex(masker(outs2, 5*cnt, 5)))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment