Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
CreateMojos.py
import random
import os
import asyncio
import math
import sys
import sqlite3
import traceback
from chia.cmds.wallet_funcs import execute_with_wallet
from chia.rpc.full_node_rpc_client import FullNodeRpcClient
from chia.types.blockchain_format.sized_bytes import bytes32
from chia.util.bech32m import decode_puzzle_hash
from chia.util.ints import uint16, uint64
from chia.util.default_root import DEFAULT_ROOT_PATH
async def main(*args, **kwargs):
try:
await split(*args, **kwargs)
except Exception:
print(traceback.format_exc())
async def split(params, wallet_rpc_client, fingerprint):
node_hostname = os.environ.get('NODE_HOSTNAME', 'node')
node_ssl_path = os.environ.get('NODE_SSL_PATH', '/data/node_ssl')
node_rpc_client = await FullNodeRpcClient.create(
node_hostname, uint16(int(os.environ.get('NODE_PORT', 8555))), DEFAULT_ROOT_PATH, {
'private_ssl_ca': {
'crt': f'{node_ssl_path}/ca/private_ca.crt',
'key': f'{node_ssl_path}/ca/private_ca.key',
},
'daemon_ssl': {
'private_crt': f'{node_ssl_path}/daemon/private_daemon.crt',
'private_key': f'{node_ssl_path}/daemon/private_daemon.key',
},
}
)
s = sqlite3.connect(f'{DEFAULT_ROOT_PATH}/wallet/db/blockchain_wallet_v1_mainnet_{fingerprint}.sqlite')
cursor = s.cursor()
cursor.execute('select puzzle_hash from derivation_paths order by derivation_index')
phs = {bytes.fromhex(i[0]) for i in cursor.fetchall()}
cursor.close()
fee = int(os.environ['FEE'])
scan = list(phs)
bigger_phs = set()
mojos_phs = set()
num = 3000
for i in range(math.ceil(len(phs) / num)):
for cr in await node_rpc_client.get_coin_records_by_puzzle_hashes(scan[i * num:(i + 1) * num], include_spent_coins=False):
if cr.coin.amount == 1:
mojos_phs.add(cr.coin.puzzle_hash)
elif cr.coin.amount > 400:
bigger_phs.add(cr.coin.puzzle_hash)
empty_phs = (phs - bigger_phs)
additions_per_tx = 400
for i in range(max(additions_per_tx * 3 - len(empty_phs), 0)):
naddr = await wallet_rpc_client.get_next_address(1, True)
ph = bytes32(decode_puzzle_hash(naddr))
empty_phs.add(ph)
run = True
while run:
run = False
for cr in await node_rpc_client.get_coin_records_by_puzzle_hashes(
list(bigger_phs), include_spent_coins=False
):
if cr.coin.amount <= 1:
try:
bigger_phs.remove(cr.coin.puzzle_hash)
except KeyError:
pass
continue
run = True
print(f"Splitting {int(cr.coin.amount)} mojos coin")
payment_targets = []
subtract = min(int(cr.coin.amount), additions_per_tx)
skip = random.randint(0, additions_per_tx * 2)
sublist = list(empty_phs)[skip:skip + subtract + 1]
for i in sublist[:subtract]:
payment_targets += [{'puzzle_hash': i, 'amount': uint64(1)}]
if cr.coin.amount > additions_per_tx:
payment_targets += [{'puzzle_hash': sublist[-1], 'amount': uint64(cr.coin.amount - additions_per_tx)}]
bigger_phs.add(sublist[-1])
empty_phs.remove(sublist[-1])
tx = await wallet_rpc_client.send_transaction_multi(
1, payment_targets, fee=uint64(fee), coins=[cr.coin],
)
while not tx.confirmed:
tx = await wallet_rpc_client.get_transaction(1, tx.name)
await asyncio.sleep(2)
print('.', end='')
sys.stdout.flush()
print("Tx confirmed")
node_rpc_client.close()
wallet_rpc_client.close()
await node_rpc_client.await_closed()
await wallet_rpc_client.await_closed()
if __name__ == '__main__':
asyncio.run(execute_with_wallet(9256, None, {}, main))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment