{"id":19139899,"url":"https://github.com/arcblock/forge-python-sdk","last_synced_at":"2025-05-06T23:15:01.547Z","repository":{"id":57431897,"uuid":"164481702","full_name":"ArcBlock/forge-python-sdk","owner":"ArcBlock","description":"Python sdk for forge","archived":false,"fork":false,"pushed_at":"2019-11-13T21:25:26.000Z","size":8056,"stargazers_count":9,"open_issues_count":4,"forks_count":0,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-05-06T23:14:54.255Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ArcBlock.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-01-07T19:29:19.000Z","updated_at":"2020-05-08T22:11:40.000Z","dependencies_parsed_at":"2022-09-02T12:40:47.565Z","dependency_job_id":null,"html_url":"https://github.com/ArcBlock/forge-python-sdk","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArcBlock%2Fforge-python-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArcBlock%2Fforge-python-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArcBlock%2Fforge-python-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArcBlock%2Fforge-python-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ArcBlock","download_url":"https://codeload.github.com/ArcBlock/forge-python-sdk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252782834,"owners_count":21803410,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T07:15:37.202Z","updated_at":"2025-05-06T23:15:01.519Z","avatar_url":"https://github.com/ArcBlock.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Gitter](https://badges.gitter.im/ArcBlock/community.svg)](https://gitter.im/ArcBlock/community?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge)\n\n![forge-python-sdk](https://www.arcblock.io/.netlify/functions/badge/?text=Forge%20Python%20SDK)\n\nFor details about how to set up Forge, please checkout [Forge](https://github.com/ArcBlock/forge).\n\nA more detailed reference manual for forge-python-sdk can be found [Here](https://docs.arcblock.io/forge-sdk/python/latest/).\n\n\n## Installation\n\nWe recommend installing through `pip`\n```sh\npip install forge-python-sdk\n```\n\nFor developers:\n```sh\npip install -r requirements.txt\n\n```\n\n## Usage\n\n### Step 0\n\nFirst get your Forge running on local with [Forge CLI](https://docs.arcblock.io/forge/latest/tools/forge_cli.html).\n\n### Step 1\nCreate a Forge Connection with your Forge port (Default is `127.0.0.1:28210` if your Forge runs with `forge-cli`)\n```python\nfrom forge_sdk import ForgeConn\nf = ForgeConn('127.0.0.1:28210')\nrpc = f.rpc\nconfig = f.config\n```\n::: warning\nThis step applies to every tutorial\n:::\n\n## Tutorials\n\n### Level 1: Transfer Money\n\n**Scenario**: Alice wants to transfer 10 TBA to Mike.\n\n::: tip Notes\n**TBA** is the default currency on Forge Chain. If 1 TBA has 16 digits, it shows as `10000000000000000`.\n:::\n\n#### Step 1: create wallets for Alice and Mike\n\n```python\nfrom forge_sdk import protos, utils\nalice = rpc.create_wallet(moniker='alice')\nmike = rpc.create_wallet(moniker='mike')\n```\n\n::: tip Notes\n`moniker` is a nickname for this wallet on Forge. `passphrase` is used by Forge to encrypt the wallet into a keystore file. More details about wallet declaration rules are [here](../intro/concepts).\n:::\n\nLet's take a look at Alice's wallet and here account details\n\n```python\n\u003e\u003e\u003e alice\ntoken: \"886fe22cd8d29a5c0d0fa5b21ec448bd\"\nwallet {\n  sk: \"\\274\\262\\331z\\000\\265\\374\\271O7f\\2640\u003c\\214\\212G\\302y\\021\\232\\363\\355.E\\207\\213\u0026\\355\\362\\260Gu\\204\\360@e\\036\\353\\357\\276\\323\\340\\211\\371U\\3716\\2212\\304\\223\\037{\\037\\366\\267\\374\\233@\\021\\215W\\027\"\n  pk: \"u\\204\\360@e\\036\\353\\357\\276\\323\\340\\211\\371U\\3716\\2212\\304\\223\\037{\\037\\366\\267\\374\\233@\\021\\215W\\027\"\n  address: \"z1brhJCteRSvHUQ9BytsZePkY4KJ9LFBayC\"\n}\n\n\u003e\u003e\u003e rpc.get_account_balance(alice.address)\n0\n```\n\n#### Step 2: Help Alice send a Poke Transaction to get some money\n\nNow you have created wallets for Alice and Mike, but there's no money in their accounts. Let's help Alice to earn some money by sending a **Poke** transaction.\n\n```python\n\u003e\u003e\u003e rpc.poke(alice)\nhash: \"CF0513E473ED13712CDB65EFC196A77BD6193E7DF5124C6233C55732573C85A2\"\n```\nReceiving the **hash** means the transaction has been passed to Forge, but doens't mean the transaction is successful. To confirm that the transaction is sent successfully, let's dive deeper into the tranaction details.\n\n```python\n\u003e\u003e\u003e rpc.is_tx_ok('CF0513E473ED13712CDB65EFC196A77BD6193E7DF5124C6233C55732573C85A2')\nTrue\n```\n\nIf `is_tx_ok` returns `True`, that means the transaction has been executed successfully. Now Alice should have 25 TBA in her account.\n\nNow let's check Alice's account balance. There should be 25 TBA.\n\n```python\n\u003e\u003e\u003e rpc.get_account_balance(alice.address)\n250000000000000000\n```\n\n::: tip Notes\n**Poke**: Each account can send a **Poke Transaction** to get 25 TBA each day.\n**Hash**: The calculated hash of the signed transaction. Each transaction should have its own unique **hash**.\n:::\n\n#### Step 3: Transfer the money from Alice to Mike\n\nNow Alice has 25 TBA in her account and Mike has nothing. We can help Alice transfer 10 TBA to Mike by sending out a **transfer transaction**.\n\n```python\nrpc.transfer(to=mike.address,value=utils.to_unit(100),wallet=alice)\n hash: \"CAEF155B1A3A684DAF57C595F68821502BC0187BEC514E4660BA1BD568474345\"\n\nrpc.is_tx_ok('CAEF155B1A3A684DAF57C595F68821502BC0187BEC514E4660BA1BD568474345')\nTrue\n\nrpc.get_account_balance(mike.address)\n101000000000000000\n```\n\nNow we can see tht Alice just successfully transferred 10 TBA to Mike's Account!\n\n 🎉 Congratulations! You have finished the Level 1 tutorial! Now you should have a general sense about how Forge works. If you want more challenges, go checkout the Level 2 tutorial.\n\n ### Level 2: Sell a Used Laptop\n\n **Scenario**: Mike wants to sell a used laptop to Alice.\n\n#### Step 1: Create accounts for Alice and Mike\n\n```python\nalice=rpc.create_wallet(moniker='alice')\nmike = rpc.create_wallet(moniker='mike')\n```\n\nAfter creating accounts for Alice and Mike, we help Alice to get some money to buy Mike's laptop\n\n```python\n\nrpc.poke(alice)\nhash: \"CF0513E473ED13712CDB65EFC196A77BD6193E7DF5124C6233C55732573C85A2\"\n\nrpc.get_account_balance(alice.address)\n250000000000000000\n```\n\n#### Step 2: Create a laptop asset for Mike\n\nIn real world, Mike could have just sold Alice his laptop. With Forge SDK, any physical item can exist in the form of **asset**.\n\nLet's try to help Mike create a laptop asset with the **CreateAssetTx**. The `data` field is for users to put item-specific information, where `type_url` is hints for how to decode the serialized `value` field. In this tutorial, for simplicity purpose, we only put the name of thel laptop.\n\n```python\nres, asset_address= rpc.create_asset('test:name:laptop', b'Laptop from Mike',mike, mike.token)\nrpc.is_tx_ok(res.hash)\nTrue\nasset_address\n'zjdwghZpZN45ig6ytP74r8VF9CHhQtEjBype'\n```\n\nThen we can see how the asset acutally look like.\n\n```python\nrpc.get_single_asset_state(asset_address)\naddress: \"zjdwghZpZN45ig6ytP74r8VF9CHhQtEjBype\"\nowner: \"z1QyzoxdPPEk9A2Uz6h18rvjsAHtmJ78mGD\"\ntransferrable: true\nissuer: \"z1QyzoxdPPEk9A2Uz6h18rvjsAHtmJ78mGD\"\nstake {\n  total_stakes {\n    value: \"\\000\"\n  }\n  total_unstakes {\n    value: \"\\000\"\n  }\n  total_received_stakes {\n    value: \"\\000\"\n  }\n  recent_stakes {\n    type_url: \"fg:x:address\"\n    max_items: 128\n    circular: true\n  }\n  recent_received_stakes {\n    type_url: \"fg:x:address\"\n    max_items: 128\n    circular: true\n  }\n}\ncontext {\n  genesis_tx: \"9EAC9AF9136D30E5C02EDD46BEF081AD61F3F722BA6FEF4398CC5FBC363DCA30\"\n  renaissance_tx: \"9EAC9AF9136D30E5C02EDD46BEF081AD61F3F722BA6FEF4398CC5FBC363DCA30\"\n  genesis_time {\n    seconds: 1557129670\n    nanos: 700917000\n  }\n  renaissance_time {\n    seconds: 1557129670\n    nanos: 700917000\n  }\n}\ndata {\n  type_url: \"test:name:laptop\"\n  value: \"Laptop from Mike\"\n}\n```\n\nThe laset field is the `data` field, where we can see `Laptop from Mike`. You can also put more complicated information inside, like serialized protobuf message.\n\n#### Step 3 : Exchange the asset with money\n\nNow Alice has 25 TBA in her account, and Mike has a laptop asset. What should Mike do if he wants to sell the laptop asset for 10 TBA? He can initiate an **ExchangeTx**.\n\nSince Mike is going to be the sender, we put the laptop `asset_address` as what he will exchange. Similarly, Alice will exchange 10 TBA.\n\n```python\nmike_exchange_info = protos.ExchangeInfo(assets=[asset_address])\nalice_exchange_info = protos.ExchangeInfo(value = utils.int_to_biguint(100000000000000000))\nexchange_tx = protos.ExchangeTx(sender = mike_exchange_info, receiver=alice_exchange_info)\n\ntx = rpc.prepare_exchange(exchange_tx, mike)\ntx = rpc.finalize_exchange(tx, alice.wallet)\nres = rpc.send_tx(tx)\n\n\u003e\u003e\u003e rpc.is_tx_ok(res.hash)\nTrue\n```\nIn the `prepare_exchange`, we ask Mike the seller to verify the transaction; and in the `finalize_exchange`, we ask Alice the buyer to verify the transaction. After both parties have verified, we can send the transaction directly.\n\nNow if we check the laptop's owner, it should be Alice's address.\n\n```python\nrpc.get_single_asset_state(asset_address).owner == alice.wallet.address\nTrue\n```\n\nAlice's account should have only 15 TBA after she pays for the laptop.\n\n```python\n\u003erpc.get_account_balance(alice.wallet.address)\n150000000000000000\n```\n\n 🎉 🎉Congratulations! You have finished the Level 2 tutorial! Now you should have a general sense about how to create an asset and exchange assets with Forge SDK. Try and create more complicated assets!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farcblock%2Fforge-python-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farcblock%2Fforge-python-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farcblock%2Fforge-python-sdk/lists"}