def main(source, name): # Create keypair for the contract owner provider1 = Entity() address1 = Address(provider1) provider2 = Entity() address2 = Address(provider2) scooter1 = Entity() scooter_address1 = Address(scooter1) # Setting API up api = LedgerApi('127.0.0.1', 8100) # Need funds to deploy contract api.sync(api.tokens.wealth(provider1, 59000000)) # Create contract contract = SmartContract(source) # Deploy contract api.sync(api.contracts.create(provider1, contract, 2456766)) if name.endswith("contract.etch"): contract.action(api, 'addProvider', 2456766, [provider2, provider1], address2, address1) contract.action(api, 'addScooter', 2456766, [provider2, provider1], address2, address1, 22, 1) print("Wait for txs to be mined ...") time.sleep(5) # Printing balance of the creating address1 print(contract.query(api, 'getFleetSize'), " scooter in fleet")
def setUp(self) -> None: self.entity = Entity() self.address = Address(self.entity) self.to_address = Address(Entity()) with patch('requests.session') as mock_session: self.api = TokenApi('127.0.0.1', 8000)
def test_drop_signee(self): deed = Deed() deed.set_signee(self.address, 10) self.assertIn(Address(self.address), deed.signees) deed.remove_signee(self.address) self.assertNotIn(Address(self.address), deed.signees)
def main(): # load up the previously created private key with open('private.key', 'r') as private_key_file: entity1 = Entity.prompt_load(private_key_file) # load up the deployed contract with open('sample.contract', 'r') as contract_file: contract = Contract.load(contract_file) # for the purposes of this example create a second private key pair to transfer funds to entity2 = Entity() # build the ledger API api = LedgerApi('127.0.0.1', 8000) # print the current status of all the tokens print('-- BEFORE --') print_address_balances(api, contract, [entity1, entity2]) # transfer from one to the other using our newly deployed contract tok_transfer_amount = 200 fet_tx_fee = 40 api.sync( contract.action(api, 'transfer', fet_tx_fee, [entity1], Address(entity1), Address(entity2), tok_transfer_amount)) print('-- AFTER --') print_address_balances(api, contract, [entity1, entity2])
def main(): # create our first private key pair entity1 = Entity() address1 = Address(entity1) # create a second private key pair entity2 = Entity() address2 = Address(entity2) # build the ledger API api = LedgerApi('127.0.0.1', 8100) # create wealth so that we have the funds to be able to create contracts on the network api.sync(api.tokens.wealth(entity1, 10000)) # create the smart contract contract = SmartContract(CONTRACT_TEXT) # deploy the contract to the network api.sync(api.contracts.create(entity1, contract, 2000)) # print the current status of all the tokens print('-- BEFORE --') print_address_balances(api, contract, [address1, address2]) # transfer from one to the other using our newly deployed contract tok_transfer_amount = 200 fet_tx_fee = 40 api.sync( contract.action(api, 'transfer', fet_tx_fee, [entity1], address1, address2, tok_transfer_amount)) print('-- BEFORE --') print_address_balances(api, contract, [address1, address2])
def main(): # In examples we use addresses which already have funds entity1 = Entity.from_hex( '6e8339a0c6d51fc58b4365bf2ce18ff2698d2b8c40bb13fcef7e1ba05df18e4b') entity2 = Entity.from_hex( 'e833c747ee0aeae29e6823e7c825d3001638bc30ffe50363f8adf2693c3286f8') address1 = Address(entity1) # create a second private key pair address2 = Address(entity2) # build the ledger API api = LedgerApi('127.0.0.1', 8000) # create the smart contract contract = Contract(CONTRACT_TEXT, entity1) with track_cost(api.tokens, entity1, "Cost of creation: "): api.sync(contract.create(api, entity1, 4000)) # print the current status of all the tokens print('-- BEFORE --') print_address_balances(api, contract, [address1, address2]) # transfer from one to the other using our newly deployed contract tok_transfer_amount = 200 fet_tx_fee = 160 with track_cost(api.tokens, entity1, "Cost of transfer: "): api.sync( contract.action(api, 'transfer', fet_tx_fee, entity1, address1, address2, tok_transfer_amount)) print('-- AFTER --') print_address_balances(api, contract, [address1, address2])
def _create_smart_contract_action_tx(cls, fee: int, from_address: AddressLike, contract_address: AddressLike, action: str, signatories: Iterable[Identity], shard_mask: BitVector) -> Transaction: tx = cls._create_skeleton_tx(fee) tx.from_address = Address(from_address) tx.target_contract(Address(contract_address), shard_mask) tx.action = str(action) for ident in signatories: tx.add_signer(ident) return tx
def prepare_contract(self, price): # Setting API up self._api = LedgerApi('127.0.0.1', 8100) self.longitude = 10 self.latitude = 10 self.scheduler = {} self.price = price self.rate = 22 self.max_count = 10 # Need funds to deploy contract self._api.sync(self._api.tokens.wealth(self._entity, 5000000)) # Create contract self._contract = SmartContract(self._source) # Deploy contract self._api.sync( self._api.contracts.create(self._entity, self._contract, 2456766)) self.chargers = [ Entity(), ] #self._contract.action(self._api, 'test', 2456755, [self._entity], Address(self.chargers[0]), Address(self.chargers[0])) self._contract.action(self._api, 'addCharger', 2456766, [self._entity], Address(self.chargers[0]), self.longitude, self.latitude, self.price, self.rate, self.max_count) scooter = Entity() scooter_start_time = 150000 scooter_end_time = 151000 tx_digest = self._contract.action(self._api, 'book', 2456766, [self._entity], Address(self.chargers[0]), Address(scooter), scooter_start_time, scooter_end_time) time.sleep(3) tx_status = self._api.tx.status(tx_digest) if tx_status == "Executed": self.scheduler[str( Address(scooter))] = [scooter_start_time, scooter_end_time] query = self._contract.query(api=self._api, name='getSlotInfo', charger=Address(self.chargers[0])) print(query)
def create(self, owner: Entity, contract: 'Contract', fee: int): ENDPOINT = 'create' # format the data to be closed by the transaction # wildcard for the moment shard_mask = BitVector() # build up the basic transaction information tx = self._create_skeleton_tx(fee) tx.from_address = Address(owner) tx.target_chain_code(self.API_PREFIX, shard_mask) tx.action = ENDPOINT tx.data = self._encode_json({ 'text': contract.encoded_source, 'digest': contract.digest.to_hex() }) tx.add_signer(owner) # encode and sign the transaction encoded_tx = encode_transaction(tx, [owner]) # update the contracts owner contract.owner = owner # submit the transaction return self._post_tx_json(encoded_tx, ENDPOINT)
def balance(self, address: AddressLike): """ Query the balance for a given address from the remote node :param address: The base64 encoded string containing the address of the node :return: The balance value retried :raises: ApiError on any failures """ # convert the input to an address address = Address(address) # format and make the request request = {'address': str(address)} success, data = self._post_json('balance', request) # check for error cases if not success: raise ApiError('Failed to request balance for address ' + str(address)) if 'balance' not in data: raise ApiError('Malformed response from server') # return the balance return int(data['balance'])
def transfer(self, entity: Entity, to: AddressLike, amount: int, fee: int): """ Transfers wealth from one account to another account :param private_key_bin: The bytes of the private key of the source address :param to_address: The bytes of the targeted address to send funds to :param amount: The amount of funds being transfered :param fee: The fee associated with the transfer :return: The digest of the submitted transaction :raises: ApiError on any failures """ ENDPOINT = 'transfer' # format the data to be closed by the transaction # wildcard for the moment shard_mask = BitVector() # build up the basic transaction information tx = Transaction() tx.from_address = Address(entity) tx.valid_until = 10000 tx.charge_rate = 1 tx.charge_limit = fee tx.add_transfer(to, amount) tx.add_signer(entity) # encode and sign the transaction encoded_tx = encode_transaction(tx, [entity]) # submit the transaction return self._post_tx_json(encoded_tx, ENDPOINT)
def prepare_contract(self, price): # Setting API up self._api = LedgerApi('127.0.0.1', 8100) self.scheduler = {} self.price = price self.rate = 22 self.max_count = 10 # Need funds to deploy contract self._api.sync(self._api.tokens.wealth(self._entity, 5000000)) # Create contract self._contract = SmartContract(self._source) # Deploy contract self._api.sync( self._api.contracts.create(self._entity, self._contract, 2456766)) self.chargers = [ Entity(), ] self._contract.action(self._api, 'addCharger', 2456766, [self._entity], Address(self.chargers[0]), int(self.latitude * 1000), int(self.longitude * 1000), self.price, self.rate, self.max_count)
def on_accept(self, msg_id: int, dialogue_id: int, origin: str, target: int): """Once we received an Accept, send the requested data.""" print("[{0}]: Received accept from {1}.".format( self.public_key, origin)) # Preparing contract # PLACE HOLDER TO PREPARE AND SIGN TRANSACTION print(self.scooterToBook) print(Address(self.scooterToBook)) print("trying to BOOK /////") #tx_digest = self._contract.action(self._api, 'book', 2456766, [self.chargers[0]], Address(self.chargers[0]), # self.scooterToBook, self.scooter_start_time, self.scooter_end_time) time.sleep(3) #print("Failed tx:", tx_digest) #tx_status = self._api.tx.status(tx_digest) #if tx_status == "Executed": # self.scheduler[self.scooterToBook] = [self.scooter_start_time, self.scooter_end_time] # encoded_data = json.dumps(tx_digest).encode("utf-8") # print("[{0}]: Sending contract to {1}".format(self.public_key, origin)) # self.send_message(0, dialogue_id, origin, encoded_data) self.scheduler[self.scooterToBook] = [ self.scooter_start_time, self.scooter_end_time ]
def call(name: str) -> SmartContract: # Create keypair for the contract owner provider1 = Entity() address1 = Address(provider1) # Setting API up api = LedgerApi('185.91.52.11', 10002) # Need funds to deploy contract api.sync(api.tokens.wealth(provider1, 59000000)) with open(name, "r") as fb: source = fb.read() # Create contract contract = SmartContract(source) # Deploy contract api.sync(api.contracts.create(provider1, contract, 2456766)) print("Wait for txs to be mined ...") time.sleep(5) # Printing balance of the creating address1 print(contract.query(api, 'getAccountRides', acc_id="1"))
def action(self, contract_digest: Address, contract_address: Address, action: str, fee: int, from_address: Address, signers: EntityList, *args, shard_mask: BitVector = None): # Default to wildcard shard mask if none supplied if not shard_mask: logging.warning( "Defaulting to wildcard shard mask as none supplied") shard_mask = BitVector() # build up the basic transaction information tx = self._create_skeleton_tx(fee) tx.from_address = Address(from_address) tx.target_contract(contract_digest, contract_address, shard_mask) tx.action = str(action) tx.data = self._encode_msgpack_payload(*args) for signer in signers: tx.add_signer(signer) encoded_tx = encode_transaction(tx, signers) return self._post_tx_json(encoded_tx, None)
def main(source, name): # Constellation HOST = '127.0.0.1' PORT = 8100 # deploy the contract to the network api = LedgerApi(HOST, PORT) # api = LedgerApi(network='alphanet') # Create keypair for the contract owner owner = Entity() owner_addr = Address(owner) # print(owner_addr) # Need funds to deploy contract api.sync(api.tokens.wealth(owner, 20000)) # Create contract contract = Contract(source, owner) # Deploy contract api.sync(api.contracts.create(owner, contract, 10000)) # Save the contract to the disk with open('sample.contract', 'w') as contract_file: contract.dump(contract_file) # Save the contract owner's private key to disk with open('owner_private.key', 'w') as private_key_file: owner.dump(private_key_file) print(f"Contract {name}.etch has successfully been deployed.")
def wealth(self, entity: Entity, amount: int): """ Creates wealth for specified account :param entity: The entity object to create wealth for :param amount: The amount of wealth to be generated :return: The digest of the submitted transaction :raises: ApiError on any failures """ ENDPOINT = 'wealth' # format the data to be closed by the transaction # wildcard for the moment shard_mask = BitVector() # build up the basic transaction information tx = self._create_skeleton_tx(1) tx.from_address = Address(entity) tx.target_chain_code(self.API_PREFIX, shard_mask) tx.action = 'wealth' tx.add_signer(entity) # format the transaction payload tx.data = self._encode_json({ 'address': entity.public_key, 'amount': amount }) # encode and sign the transaction encoded_tx = encode_transaction(tx, [entity]) # submit the transaction return self._post_tx_json(encoded_tx, ENDPOINT)
def main(): entity = Entity.from_hex( '6e8339a0c6d51fc58b4365bf2ce18ff2698d2b8c40bb13fcef7e1ba05df18e4b') address = Address(entity) print('Address:', address) # create the APIs api = LedgerApi(HOST, PORT) # Display balance before print('Balance:', api.tokens.balance(entity)) print('Stake..:', api.tokens.stake(entity)) # submit and wait for the transfer to be complete print('Submitting stake request...') api.sync(api.tokens.add_stake(entity, 1000, 50)) while True: print('Balance............:', api.tokens.balance(entity)) print('Stake..............:', api.tokens.stake(entity)) print('Stake on cooldown..:', api.tokens.stake_cooldown(entity)) # De-stake half of the staked balance to_destake = int(api.tokens.stake(entity) / 2) api.sync(api.tokens.de_stake(entity, to_destake, 500)) # Collect cooled down stakes api.sync(api.tokens.collect_stake(entity, 500)) time.sleep(1)
def validate_transaction( self, tx_digest: str, seller: Address, client: Address, tx_nonce: str, amount: int, ) -> bool: """ Check whether a transaction is valid or not. :param seller: the address of the seller. :param client: the address of the client. :param tx_nonce: the transaction nonce. :param amount: the amount we expect to get from the transaction. :param tx_digest: the transaction digest. :return: True if the random_message is equals to tx['input'] """ tx_contents = cast(TxContents, self._api.tx.contents(tx_digest)) transfers = tx_contents.transfers seller_address = Address(seller) is_valid = (str(tx_contents.from_address) == client and amount == transfers[seller_address]) # TODO: Add the tx_nonce check here when the ledger supports extra data to the tx. is_settled = self.is_transaction_settled(tx_digest=tx_digest) result = is_valid and is_settled return result
def prepare_contract(self, price): # Setting API up self._api = LedgerApi('127.0.0.1', 8100) self.scheduler = {} self.price = price self.rate = 20 self.max_count = 10 # Need funds to deploy contract self._api.sync(self._api.tokens.wealth(self._entity, 5000000)) # Create contract #self._contract = SmartContract(self._source) # Deploy contract #self._api.sync(self._api.contracts.create(self._entity, self._contract, 2456766)) with open('contract.txt','r') as ff: self.digest = ff.readline().split('\n')[0] self.owner = ff.readline() self.chargers = [Entity(), ] self._api.contracts.action(self.digest, self.owner, 'addCharger', 2456766, [self._entity], Address(self.chargers[0]), self.latitude, self.longitude, self.price, self.rate, self.max_count)
def assertKeyIsPresentOnDisk(self, name: str, password: str, entity: Entity, ctx: TemporaryPocketBookRoot): self.assertTrue(os.path.isdir(ctx.root)) # check that the index record has been created correctly index_path = os.path.join(ctx.root, KeyStore.INDEX_FILE_NAME) self.assertTrue(os.path.isfile(index_path)) with open(index_path, 'r') as index_file: index = toml.load(index_path) # build up the key listings key_addresses = { key['name']: key['address'] for key in index.get('key', []) } # ensure the key is reference in the index self.assertIn(name, key_addresses.keys()) # also ensure the computed address is also correct expected_address = Address(entity) self.assertEqual(key_addresses[name], str(expected_address)) # check the contents of the key key_path = os.path.join(ctx.root, '{}.key'.format(name)) self.assertTrue(os.path.isfile(key_path)) with open(key_path, 'r') as key_file: recovered = Entity.load(key_file, password) self.assertEqual(recovered.private_key, entity.private_key)
def on_cfp(self, msg_id: int, dialogue_id: int, origin: str, target: int, query: CFP_TYPES): """Send a simple Propose to the sender of the CFP.""" print("[{0}]: Received CFP from {1}".format(self.public_key, origin)) price = self.price timeArr = [] for key in self.scheduler.keys(): timeArr.append(self.scheduler[key]) # prepare the proposal with a given price. proposal = Description({ "price_per_energy_percent": price, "digest": str(self._contract), "longitude": self.longitude, "latitude": self.latitude, "scheduler": json.dumps(timeArr), "rate": self.rate, "max_count": self.max_count, "charger_address": str(Address(self.chargers[0])) }) print("[{}]: Sending propose at price: {}".format( self.public_key, price)) self.send_propose(msg_id + 1, dialogue_id, origin, target + 1, [proposal])
def print_address_balances(api: LedgerApi, contract: Contract, addresses: List[Address]): for idx, address in enumerate(addresses): print('Address{}: {:<6d} bFET {:<10d} TOK'.format( idx, api.tokens.balance(address), contract.query(api, 'balance', address=Address(address)))) print()
def de_stake(self, entity: Entity, amount: int, fee: int): """ Destakes a specific amount of tokens from a staking miner. This will put the tokens in a cool down period :param entity: The entity object that desires to destake :param amount: The amount of tokens to destake :return: The digest of the submitted transaction :raises: ApiError on any failures """ ENDPOINT = 'deStake' # format the data to be closed by the transaction # wildcard for the moment shard_mask = BitVector() # build up the basic transaction information tx = self._create_skeleton_tx(fee) tx.from_address = Address(entity) tx.target_chain_code(self.API_PREFIX, shard_mask) tx.action = 'deStake' tx.add_signer(entity) # format the transaction payload tx.data = self._encode_json({ 'address': entity.public_key, 'amount': amount }) # encode and sign the transaction encoded_tx = encode_transaction(tx, [entity]) # submit the transaction return self._post_tx_json(encoded_tx, ENDPOINT)
def run(options, benefactor): # Create keypair for the contract owner entity = Entity() Address(entity) host = options['host'] port = options['port'] # create the APIs api = LedgerApi(host, port) # Transfer tokens from benefactor api.sync(api.tokens.transfer(benefactor, entity, int(1e7), 1000)) # Load contract source source_file = os.path.join(HERE, "hello_world.etch") with open(source_file, "r") as fb: source = fb.read() # Create contract contract = Contract(source, entity) # Deploy contract api.sync(api.contracts.create(entity, contract, 10000)) # Printing message print(contract.query(api, 'persistentGreeting'))
def collect_stake(self, entity: Entity, fee: int): """ Collect all stakes that have reached the end of the cooldown period :param entity: The entity object that desires to collect :return: The digest of the submitted transaction :raises: ApiError on any failures """ ENDPOINT = 'collectStake' # format the data to be closed by the transaction # wildcard for the moment shard_mask = BitVector() # build up the basic transaction information tx = self._create_skeleton_tx(fee) tx.from_address = Address(entity) tx.target_chain_code(self.API_PREFIX, shard_mask) tx.action = 'collectStake' tx.add_signer(entity) # encode and sign the transaction encoded_tx = encode_transaction(tx, [entity]) # submit the transaction return self._post_tx_json(encoded_tx, ENDPOINT)
def decide_on_proposals(self): print('Got proposals:', self.saved_proposals) proposals = [{ 'address': p[1].values['charger_address'], 'longitude': p[1].values['longitude'], 'latitude': p[1].values['latitude'], 'max_count': p[1].values['max_count'], 'scheduler': json.loads(p[1].values['scheduler']), 'args': p[0] } for p in self.saved_proposals] trajectory = [(1, 1), (3, 4), (6, 4), (7, 6), (8, 8)] best_proposal, best_slot = find_best(trajectory, proposals, 100, 0.00001, 1, 0.1) dict = { 'address': str(Address(self.scooters[0])), 'startTime': best_slot[0], 'endTime': best_slot[1] } encoded_data = json.dumps(dict).encode("utf-8") print("[{0}]: Sending contract to {1}".format( self.public_key, best_proposal['args'][2])) self.send_message(0, best_proposal['args'][1], best_proposal['args'][2], encoded_data) time.sleep(5) self.send_accept(best_proposal['args'][0], best_proposal['args'][1], best_proposal['args'][2], best_proposal['args'][3])
def create(self, owner: Entity, contract: 'Contract', fee: int, shard_mask: BitVector = None): ENDPOINT = 'create' logging.debug('Deploying contract', contract.address) # Default to wildcard shard mask if none supplied if not shard_mask: logging.warning( "Defaulting to wildcard shard mask as none supplied") shard_mask = BitVector() # build up the basic transaction information tx = self._create_skeleton_tx(fee) tx.from_address = Address(owner) tx.target_chain_code(self.API_PREFIX, shard_mask) tx.action = ENDPOINT tx.data = self._encode_json({ 'nonce': contract.nonce, 'text': contract.encoded_source, 'digest': contract.digest.to_hex() }) tx.add_signer(owner) # encode and sign the transaction encoded_tx = encode_transaction(tx, [owner]) # update the contracts owner contract.owner = owner # submit the transaction return self._post_tx_json(encoded_tx, ENDPOINT)
def test_static_constructor(self): data = { 'digest': '0x123456', 'action': 'transfer', 'chainCode': 'action.transfer', 'from': 'U5dUjGzmAnajivcn4i9K4HpKvoTvBrDkna1zePXcwjdwbz1yB', 'validFrom': 0, 'validUntil': 100, 'charge': 2, 'chargeLimit': 5, 'transfers': [], 'signatories': ['abc'], 'data': 'def' } a = TxContents.from_json(data) self.assertEqual(a._digest_bytes, bytes.fromhex('123456')) self.assertEqual(a._digest_hex, '123456') self.assertEqual(a.action, 'transfer') self.assertEqual(a.chain_code, 'action.transfer') self.assertEqual( a.from_address, Address('U5dUjGzmAnajivcn4i9K4HpKvoTvBrDkna1zePXcwjdwbz1yB')) self.assertIsNone(a.contract_digest) self.assertIsNone(a.contract_address) self.assertEqual(a.valid_from, 0) self.assertEqual(a.valid_until, 100) self.assertEqual(a.charge, 2) self.assertEqual(a.charge_limit, 5) self.assertEqual(a.transfers, {}) self.assertEqual(a.data, 'def')
def generate_fetchai_wealth(arguments: argparse.Namespace) -> None: """ Generate tokens to be able to make a transaction. :param arguments: the arguments :return: None """ try: api = LedgerApi(arguments.addr, arguments.port) except Exception: logging.info("Couldn't connect! Please check your add and port.") sys.exit(1) try: if arguments.private_key is None or arguments.private_key == "": raise ValueError except ValueError: logging.error("Please provide a private key. --private-key .... ") sys.exit(1) logging.info("Waiting for token wealth generation...") entity_to_generate_wealth = Entity.from_hex( Path(arguments.private_key).read_text()) api.sync(api.tokens.wealth(entity_to_generate_wealth, arguments.amount)) address = Address(entity_to_generate_wealth) balance = api.tokens.balance(address) logging.info('The new balance of the address {} is : {} FET'.format( address, balance))