Exemplo n.º 1
0
def login(username, password):
    st = steem.Steem(['https://ws.testnet3.golos.io'])
    if not st.steemd.login(username, password):
        return None

    private_key = PasswordKey(username, password, 'posting')
    st.commit.wallet.setKeys(str(private_key.get_private()))
    return User(username, password, st)
Exemplo n.º 2
0
    def __init__(self):
        self._steem = steem.Steem(['https://ws.testnet3.golos.io'])
        self._username = '******'
        self._password = '******'
        if not self._steem.steemd.login(self._username, self._password):
            raise RuntimeError('ChainMaster login failed!')

        key = PasswordKey(self._username, self._password, 'posting')
        self._steem.commit.wallet.setKeys(str(key.get_private()))
Exemplo n.º 3
0
def wallet():
    import_wifForm = forms.ImportWifKey()
    import_accountpwd = forms.ImportAccountPassword()

    if request.method == 'POST' and steem.wallet.locked():
        flash("Wallet is locked!")

    elif request.method == 'POST' and "import_wif" in request.form:
        if import_wifForm.validate():
            steem.wallet.addPrivateKey(import_wifForm.wif.data)

    elif request.method == 'POST' and "import_accountpwd" in request.form:
        if import_accountpwd.validate():
            from steembase.account import PasswordKey
            keyImported = False
            for role in ["active", "posting", "memo"]:  # do not add owner key!
                priv = PasswordKey(import_accountpwd.accountname.data,
                                   import_accountpwd.password.data,
                                   role).get_private_key()
                pub = format(priv.pubkey, "STM")
                importName = steem.wallet.getAccountFromPublicKey(pub)
                if importName:
                    configStore["web:user"] = importName
                    try:
                        steem.wallet.addPrivateKey(str(priv))
                    except:
                        flash("Key seems to be installed already!", "error")

                    keyImported = True
            if not keyImported:
                flash(
                    "The account could not be imported. "
                    "Verify your password!", "error")

    return render_template('wallet.html', **locals())
Exemplo n.º 4
0
 def test_PasswordKey(self):
     a = [
         "Aang7foN3oz1Ungai2qua5toh3map8ladei1eem2ohsh2shuo8aeji9Thoseo7ah",
         "iep1Mees9eghiifahwei5iidi0Sazae9aigaeT7itho3quoo2dah5zuvobaelau5",
         "ohBeuyoothae5aer9odaegh5Eeloh1fi7obei9ahSh0haeYuas1sheehaiv5LaiX",
         "geiQuoo9NeeLoaZee0ain3Ku1biedohsesien4uHo1eib1ahzaesh5shae3iena7",
         "jahzeice6Ix8ohBo3eik9pohjahgeegoh9sahthai1aeMahs8ki7Iub1oojeeSuo",
         "eiVahHoh2hi4fazah9Tha8loxeeNgequaquuYee6Shoopo3EiWoosheeX6yohg2o",
         "PheeCh3ar8xoofoiphoo4aisahjiiPah4vah0eeceiJ2iyeem9wahyupeithah9T",
         "IuyiibahNgieshei2eeFu8aic1IeMae9ooXi9jaiwaht4Wiengieghahnguang0U",
         "Ipee1quee7sheughemae4eir8pheix3quac3ei0Aquo9ohieLaeseeh8AhGeM2ew",
         "Tech5iir0aP6waiMeiHoph3iwoch4iijoogh0zoh9aSh6Ueb2Dee5dang1aa8IiP"
     ]
     b = [
         "STM5NyCrrXHmdikC6QPRAPoDjSHVQJe3WC5bMZuF6YhqhSsfYfjhN",
         "STM8gyvJtYyv5ZbT2ZxbAtgufQ5ovV2bq6EQp4YDTzQuSwyg7Ckry",
         "STM7yE71iVPSpaq8Ae2AmsKfyFxA8pwYv5zgQtCnX7xMwRUQMVoGf",
         "STM5jRgWA2kswPaXsQNtD2MMjs92XfJ1TYob6tjHtsECg2AusF5Wo",
         "STM6XHwVxcP6zP5NV1jUbG6Kso9m8ZG9g2CjDiPcZpAxHngx6ATPB",
         "STM59X1S4ofTAeHd1iNHDGxim5GkLo2AdcznksUsSYGU687ywB5WV",
         "STM6BPPL4iSRbFVVN8v3BEEEyDsC1STRK7Ba9ewQ4Lqvszn5J8VAe",
         "STM7cdK927wj95ptUrCk6HKWVeF74LG5cTjDTV22Z3yJ4Xw8xc9qp",
         "STM7VNFRjrE1hs1CKpEAP9NAabdFpwvzYXRKvkrVBBv2kTQCbNHz7",
         "STM7ZZFhEBjujcKjkmY31i1spPMx6xDSRhkursZLigi2HKLuALe5t",
     ]
     for i, pwd in enumerate(a):
         p = format(
             PasswordKey("xeroc", pwd, "posting").get_public(), "STM")
         self.assertEqual(p, b[i])
Exemplo n.º 5
0
import steem
import steembase
from steembase.account import PasswordKey
from steembase.account import PrivateKey
from steembase import operations

account = input('Account: ')
old_password = input('Current password: '******'New password: '******'https://testnet.steem.vc'], keys=[wif])

new_public_keys = {}

for role in ["owner", "active", "posting", "memo"]:
    private_key = PasswordKey(account, new_password, role).get_private_key()
    new_public_keys[role] = str(private_key.pubkey)

new_data = {
    "account": account,
    "json_metadata": {},
    "owner": {
        "key_auths": [
            [new_public_keys["owner"], 1]
        ],
Exemplo n.º 6
0
def legacy():
    """
    Piston like cli application.
    This will be re-written as a @click app in the future.
    """
    global args

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description="Command line tool to interact with the Steem network"
    )

    """
        Default settings for all tools
    """
    parser.add_argument(
        '--node',
        type=str,
        default=configStorage["node"],
        help='URL for public Steem API (default: "https://api.steemit.com")'
    )

    parser.add_argument(
        '--no-broadcast', '-d',
        action='store_true',
        help='Do not broadcast anything'
    )
    parser.add_argument(
        '--no-wallet', '-p',
        action='store_true',
        help='Do not load the wallet'
    )
    parser.add_argument(
        '--unsigned', '-x',
        action='store_true',
        help='Do not try to sign the transaction'
    )
    parser.add_argument(
        '--expires', '-e',
        default=60,
        help='Expiration time in seconds (defaults to 30)'
    )
    parser.add_argument(
        '--verbose', '-v',
        type=int,
        default=3,
        help='Verbosity'
    )
    parser.add_argument(
        '--version',
        action='version',
        version='%(prog)s {version}'.format(
            version=pkg_resources.require("steem")[0].version
        )
    )

    subparsers = parser.add_subparsers(help='sub-command help')

    """
        Command "set"
    """
    setconfig = subparsers.add_parser('set', help='Set configuration')
    setconfig.add_argument(
        'key',
        type=str,
        choices=availableConfigurationKeys,
        help='Configuration key'
    )
    setconfig.add_argument(
        'value',
        type=str,
        help='Configuration value'
    )
    setconfig.set_defaults(command="set")

    """
        Command "config"
    """
    configconfig = subparsers.add_parser('config', help='Show local configuration')
    configconfig.set_defaults(command="config")

    """
        Command "info"
    """
    parser_info = subparsers.add_parser('info', help='Show basic STEEM blockchain info')
    parser_info.set_defaults(command="info")
    parser_info.add_argument(
        'objects',
        nargs='*',
        type=str,
        help='General information about the blockchain, a block, an account name, a post, a public key, ...'
    )

    """
        Command "changewalletpassphrase"
    """
    changepasswordconfig = subparsers.add_parser('changewalletpassphrase', help='Change wallet password')
    changepasswordconfig.set_defaults(command="changewalletpassphrase")

    """
        Command "addkey"
    """
    addkey = subparsers.add_parser('addkey', help='Add a new key to the wallet')
    addkey.add_argument(
        '--unsafe-import-key',
        nargs='*',
        type=str,
        help='private key to import into the wallet (unsafe, unless you delete your bash history)'
    )
    addkey.set_defaults(command="addkey")

    """
        Command "delkey"
    """
    delkey = subparsers.add_parser('delkey', help='Delete keys from the wallet')
    delkey.add_argument(
        'pub',
        nargs='*',
        type=str,
        help='the public key to delete from the wallet'
    )
    delkey.set_defaults(command="delkey")

    """
        Command "getkey"
    """
    getkey = subparsers.add_parser('getkey', help='Dump the privatekey of a pubkey from the wallet')
    getkey.add_argument(
        'pub',
        type=str,
        help='the public key for which to show the private key'
    )
    getkey.set_defaults(command="getkey")

    """
        Command "listkeys"
    """
    listkeys = subparsers.add_parser('listkeys', help='List available keys in your wallet')
    listkeys.set_defaults(command="listkeys")

    """
        Command "listaccounts"
    """
    listaccounts = subparsers.add_parser('listaccounts', help='List available accounts in your wallet')
    listaccounts.set_defaults(command="listaccounts")

    """
        Command "upvote"
    """
    parser_upvote = subparsers.add_parser('upvote', help='Upvote a post')
    parser_upvote.set_defaults(command="upvote")
    parser_upvote.add_argument(
        'post',
        type=str,
        help='@author/permlink-identifier of the post to upvote to (e.g. @xeroc/python-steem-0-1)'
    )
    parser_upvote.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='The voter account name'
    )
    parser_upvote.add_argument(
        '--weight',
        type=float,
        default=configStorage["default_vote_weight"],
        required=False,
        help='Actual weight (from 0.1 to 100.0)'
    )

    """
        Command "downvote"
    """
    parser_downvote = subparsers.add_parser('downvote', help='Downvote a post')
    parser_downvote.set_defaults(command="downvote")
    parser_downvote.add_argument(
        '--account',
        type=str,
        default=configStorage["default_account"],
        help='The voter account name'
    )
    parser_downvote.add_argument(
        'post',
        type=str,
        help='@author/permlink-identifier of the post to downvote to (e.g. @xeroc/python-steem-0-1)'
    )
    parser_downvote.add_argument(
        '--weight',
        type=float,
        default=configStorage["default_vote_weight"],
        required=False,
        help='Actual weight (from 0.1 to 100.0)'
    )

    """
        Command "transfer"
    """
    parser_transfer = subparsers.add_parser('transfer', help='Transfer STEEM')
    parser_transfer.set_defaults(command="transfer")
    parser_transfer.add_argument(
        'to',
        type=str,
        help='Recipient'
    )
    parser_transfer.add_argument(
        'amount',
        type=float,
        help='Amount to transfer'
    )
    parser_transfer.add_argument(
        'asset',
        type=str,
        choices=["STEEM", "SBD"],
        help='Asset to transfer (i.e. STEEM or SDB)'
    )
    parser_transfer.add_argument(
        'memo',
        type=str,
        nargs="?",
        default="",
        help='Optional memo'
    )
    parser_transfer.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Transfer from this account'
    )

    """
        Command "powerup"
    """
    parser_powerup = subparsers.add_parser('powerup', help='Power up (vest STEEM as STEEM POWER)')
    parser_powerup.set_defaults(command="powerup")
    parser_powerup.add_argument(
        'amount',
        type=str,
        help='Amount of VESTS to powerup'
    )
    parser_powerup.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Powerup from this account'
    )
    parser_powerup.add_argument(
        '--to',
        type=str,
        required=False,
        default=None,
        help='Powerup this account'
    )

    """
        Command "powerdown"
    """
    parser_powerdown = subparsers.add_parser('powerdown', help='Power down (start withdrawing STEEM from steem POWER)')
    parser_powerdown.set_defaults(command="powerdown")
    parser_powerdown.add_argument(
        'amount',
        type=str,
        help='Amount of VESTS to powerdown'
    )
    parser_powerdown.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='powerdown from this account'
    )

    """
        Command "powerdownroute"
    """
    parser_powerdownroute = subparsers.add_parser('powerdownroute', help='Setup a powerdown route')
    parser_powerdownroute.set_defaults(command="powerdownroute")
    parser_powerdownroute.add_argument(
        'to',
        type=str,
        default=configStorage["default_account"],
        help='The account receiving either VESTS/SteemPower or STEEM.'
    )
    parser_powerdownroute.add_argument(
        '--percentage',
        type=float,
        default=100,
        help='The percent of the withdraw to go to the "to" account'
    )
    parser_powerdownroute.add_argument(
        '--account',
        type=str,
        default=configStorage["default_account"],
        help='The account which is powering down'
    )
    parser_powerdownroute.add_argument(
        '--auto_vest',
        action='store_true',
        help=('Set to true if the from account should receive the VESTS as'
              'VESTS, or false if it should receive them as STEEM.')
    )

    """
        Command "convert"
    """
    parser_convert = subparsers.add_parser('convert', help='Convert STEEMDollars to Steem (takes a week to settle)')
    parser_convert.set_defaults(command="convert")
    parser_convert.add_argument(
        'amount',
        type=float,
        help='Amount of SBD to convert'
    )
    parser_convert.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Convert from this account'
    )

    """
        Command "balance"
    """
    parser_balance = subparsers.add_parser('balance', help='Show the balance of one more more accounts')
    parser_balance.set_defaults(command="balance")
    parser_balance.add_argument(
        'account',
        type=str,
        nargs="*",
        default=configStorage["default_account"],
        help='balance of these account (multiple accounts allowed)'
    )

    """
        Command "interest"
    """
    interest = subparsers.add_parser('interest', help='Get information about interest payment')
    interest.set_defaults(command="interest")
    interest.add_argument(
        'account',
        type=str,
        nargs="*",
        default=configStorage["default_account"],
        help='Inspect these accounts'
    )

    """
        Command "permissions"
    """
    parser_permissions = subparsers.add_parser('permissions', help='Show permissions of an account')
    parser_permissions.set_defaults(command="permissions")
    parser_permissions.add_argument(
        'account',
        type=str,
        nargs="?",
        default=configStorage["default_account"],
        help='Account to show permissions for'
    )

    """
        Command "allow"
    """
    parser_allow = subparsers.add_parser('allow', help='Allow an account/key to interact with your account')
    parser_allow.set_defaults(command="allow")
    parser_allow.add_argument(
        '--account',
        type=str,
        nargs="?",
        default=configStorage["default_account"],
        help='The account to allow action for'
    )
    parser_allow.add_argument(
        'foreign_account',
        type=str,
        nargs="?",
        help='The account or key that will be allowed to interact as your account'
    )
    parser_allow.add_argument(
        '--permission',
        type=str,
        default="posting",
        choices=["owner", "posting", "active"],
        help='The permission to grant (defaults to "posting")'
    )
    parser_allow.add_argument(
        '--weight',
        type=int,
        default=None,
        help=('The weight to use instead of the (full) threshold. '
              'If the weight is smaller than the threshold, '
              'additional signatures are required')
    )
    parser_allow.add_argument(
        '--threshold',
        type=int,
        default=None,
        help=('The permission\'s threshold that needs to be reached '
              'by signatures to be able to interact')
    )

    """
        Command "disallow"
    """
    parser_disallow = subparsers.add_parser('disallow',
                                            help='Remove allowance an account/key to interact with your account')
    parser_disallow.set_defaults(command="disallow")
    parser_disallow.add_argument(
        '--account',
        type=str,
        nargs="?",
        default=configStorage["default_account"],
        help='The account to disallow action for'
    )
    parser_disallow.add_argument(
        'foreign_account',
        type=str,
        help='The account or key whose allowance to interact as your account will be removed'
    )
    parser_disallow.add_argument(
        '--permission',
        type=str,
        default="posting",
        choices=["owner", "posting", "active"],
        help='The permission to remove (defaults to "posting")'
    )
    parser_disallow.add_argument(
        '--threshold',
        type=int,
        default=None,
        help=('The permission\'s threshold that needs to be reached '
              'by signatures to be able to interact')
    )

    """
        Command "newaccount"
    """
    parser_newaccount = subparsers.add_parser('newaccount', help='Create a new account')
    parser_newaccount.set_defaults(command="newaccount")
    parser_newaccount.add_argument(
        'accountname',
        type=str,
        help='New account name'
    )
    parser_newaccount.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Account that pays the fee'
    )
    parser_newaccount.add_argument(
        '--fee',
        type=str,
        required=False,
        default='0 STEEM',
        help='Base Fee to pay. Delegate the rest.'
    )

    """
        Command "importaccount"
    """
    parser_importaccount = subparsers.add_parser('importaccount', help='Import an account using a passphrase')
    parser_importaccount.set_defaults(command="importaccount")
    parser_importaccount.add_argument(
        'account',
        type=str,
        help='Account name'
    )
    parser_importaccount.add_argument(
        '--roles',
        type=str,
        nargs="*",
        default=["active", "posting", "memo"],  # no owner
        help='Import specified keys (owner, active, posting, memo)'
    )

    """
        Command "updateMemoKey"
    """
    parser_updateMemoKey = subparsers.add_parser('updatememokey', help='Update an account\'s memo key')
    parser_updateMemoKey.set_defaults(command="updatememokey")
    parser_updateMemoKey.add_argument(
        '--account',
        type=str,
        nargs="?",
        default=configStorage["default_account"],
        help='The account to updateMemoKey action for'
    )
    parser_updateMemoKey.add_argument(
        '--key',
        type=str,
        default=None,
        help='The new memo key'
    )

    """
        Command "approvewitness"
    """
    parser_approvewitness = subparsers.add_parser('approvewitness', help='Approve a witnesses')
    parser_approvewitness.set_defaults(command="approvewitness")
    parser_approvewitness.add_argument(
        'witness',
        type=str,
        help='Witness to approve'
    )
    parser_approvewitness.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Your account'
    )

    """
        Command "disapprovewitness"
    """
    parser_disapprovewitness = subparsers.add_parser('disapprovewitness', help='Disapprove a witnesses')
    parser_disapprovewitness.set_defaults(command="disapprovewitness")
    parser_disapprovewitness.add_argument(
        'witness',
        type=str,
        help='Witness to disapprove'
    )
    parser_disapprovewitness.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Your account'
    )

    """
        Command "sign"
    """
    parser_sign = subparsers.add_parser('sign', help='Sign a provided transaction with available and required keys')
    parser_sign.set_defaults(command="sign")
    parser_sign.add_argument(
        '--file',
        type=str,
        required=False,
        help='Load transaction from file. If "-", read from stdin (defaults to "-")'
    )

    """
        Command "broadcast"
    """
    parser_broadcast = subparsers.add_parser('broadcast', help='broadcast a signed transaction')
    parser_broadcast.set_defaults(command="broadcast")
    parser_broadcast.add_argument(
        '--file',
        type=str,
        required=False,
        help='Load transaction from file. If "-", read from stdin (defaults to "-")'
    )

    """
        Command "orderbook"
    """
    orderbook = subparsers.add_parser('orderbook', help='Obtain orderbook of the internal market')
    orderbook.set_defaults(command="orderbook")
    orderbook.add_argument(
        '--chart',
        action='store_true',
        help="Enable charting (requires matplotlib)"
    )

    """
        Command "buy"
    """
    parser_buy = subparsers.add_parser('buy', help='Buy STEEM or SBD from the internal market')
    parser_buy.set_defaults(command="buy")
    parser_buy.add_argument(
        'amount',
        type=float,
        help='Amount to buy'
    )
    parser_buy.add_argument(
        'asset',
        type=str,
        choices=["STEEM", "SBD"],
        help='Asset to buy (i.e. STEEM or SDB)'
    )
    parser_buy.add_argument(
        'price',
        type=float,
        help='Limit buy price denoted in (SBD per STEEM)'
    )
    parser_buy.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Buy with this account (defaults to "default_account")'
    )

    """
        Command "sell"
    """
    parser_sell = subparsers.add_parser('sell', help='Sell STEEM or SBD from the internal market')
    parser_sell.set_defaults(command="sell")
    parser_sell.add_argument(
        'amount',
        type=float,
        help='Amount to sell'
    )
    parser_sell.add_argument(
        'asset',
        type=str,
        choices=["STEEM", "SBD"],
        help='Asset to sell (i.e. STEEM or SDB)'
    )
    parser_sell.add_argument(
        'price',
        type=float,
        help='Limit sell price denoted in (SBD per STEEM)'
    )
    parser_sell.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Sell from this account (defaults to "default_account")'
    )
    """
        Command "cancel"
    """
    parser_cancel = subparsers.add_parser('cancel', help='Cancel order in the internal market')
    parser_cancel.set_defaults(command="cancel")
    parser_cancel.add_argument(
        'orderid',
        type=int,
        help='Orderid'
    )
    parser_cancel.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Cancel from this account (defaults to "default_account")'
    )

    """
        Command "resteem"
    """
    parser_resteem = subparsers.add_parser('resteem', help='Resteem an existing post')
    parser_resteem.set_defaults(command="resteem")
    parser_resteem.add_argument(
        'identifier',
        type=str,
        help='@author/permlink-identifier of the post to resteem'
    )
    parser_resteem.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Resteem as this user (requires to have the key installed in the wallet)'
    )

    """
        Command "follow"
    """
    parser_follow = subparsers.add_parser('follow', help='Follow another account')
    parser_follow.set_defaults(command="follow")
    parser_follow.add_argument(
        'follow',
        type=str,
        help='Account to follow'
    )
    parser_follow.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Follow from this account'
    )
    parser_follow.add_argument(
        '--what',
        type=str,
        required=False,
        nargs="*",
        default=["blog"],
        help='Follow these objects (defaults to "blog")'
    )

    """
        Command "unfollow"
    """
    parser_unfollow = subparsers.add_parser('unfollow', help='unfollow another account')
    parser_unfollow.set_defaults(command="unfollow")
    parser_unfollow.add_argument(
        'unfollow',
        type=str,
        help='Account to unfollow'
    )
    parser_unfollow.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Unfollow from this account'
    )
    parser_unfollow.add_argument(
        '--what',
        type=str,
        required=False,
        nargs="*",
        default=[],
        help='Unfollow these objects (defaults to "blog")'
    )

    """
        Command "setprofile"
    """
    parser_setprofile = subparsers.add_parser('setprofile', help='Set a variable in an account\'s profile')
    parser_setprofile.set_defaults(command="setprofile")
    parser_setprofile.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='setprofile as this user (requires to have the key installed in the wallet)'
    )
    parser_setprofile_a = parser_setprofile.add_argument_group('Multiple keys at once')
    parser_setprofile_a.add_argument(
        '--pair',
        type=str,
        nargs='*',
        help='"Key=Value" pairs'
    )
    parser_setprofile_b = parser_setprofile.add_argument_group('Just a single key')
    parser_setprofile_b.add_argument(
        'variable',
        type=str,
        nargs='?',
        help='Variable to set'
    )
    parser_setprofile_b.add_argument(
        'value',
        type=str,
        nargs='?',
        help='Value to set'
    )

    """
        Command "delprofile"
    """
    parser_delprofile = subparsers.add_parser('delprofile', help='Set a variable in an account\'s profile')
    parser_delprofile.set_defaults(command="delprofile")
    parser_delprofile.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='delprofile as this user (requires to have the key installed in the wallet)'
    )
    parser_delprofile.add_argument(
        'variable',
        type=str,
        nargs='*',
        help='Variable to set'
    )

    """
        Command "witnessupdate"
    """
    parser_witnessprops = subparsers.add_parser('witnessupdate', help='Change witness properties')
    parser_witnessprops.set_defaults(command="witnessupdate")
    parser_witnessprops.add_argument(
        '--witness',
        type=str,
        default=configStorage["default_account"],
        help='Witness name'
    )
    parser_witnessprops.add_argument(
        '--maximum_block_size',
        type=float,
        required=False,
        help='Max block size'
    )
    parser_witnessprops.add_argument(
        '--account_creation_fee',
        type=float,
        required=False,
        help='Account creation fee'
    )
    parser_witnessprops.add_argument(
        '--sbd_interest_rate',
        type=float,
        required=False,
        help='SBD interest rate in percent'
    )
    parser_witnessprops.add_argument(
        '--url',
        type=str,
        required=False,
        help='Witness URL'
    )
    parser_witnessprops.add_argument(
        '--signing_key',
        type=str,
        required=False,
        help='Signing Key'
    )

    """
        Command "witnesscreate"
    """
    parser_witnesscreate = subparsers.add_parser('witnesscreate', help='Create a witness')
    parser_witnesscreate.set_defaults(command="witnesscreate")
    parser_witnesscreate.add_argument(
        'witness',
        type=str,
        help='Witness name'
    )
    parser_witnesscreate.add_argument(
        'signing_key',
        type=str,
        help='Signing Key'
    )
    parser_witnesscreate.add_argument(
        '--maximum_block_size',
        type=float,
        default="65536",
        help='Max block size'
    )
    parser_witnesscreate.add_argument(
        '--account_creation_fee',
        type=float,
        default=30,
        help='Account creation fee'
    )
    parser_witnesscreate.add_argument(
        '--sbd_interest_rate',
        type=float,
        default=0.0,
        help='SBD interest rate in percent'
    )
    parser_witnesscreate.add_argument(
        '--url',
        type=str,
        default="",
        help='Witness URL'
    )

    """
        Parse Arguments
    """
    args = parser.parse_args()

    # Logging
    log = logging.getLogger(__name__)
    verbosity = ["critical",
                 "error",
                 "warn",
                 "info",
                 "debug"][int(min(args.verbose, 4))]
    log.setLevel(getattr(logging, verbosity.upper()))
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    ch = logging.StreamHandler()
    ch.setLevel(getattr(logging, verbosity.upper()))
    ch.setFormatter(formatter)
    log.addHandler(ch)

    # GrapheneAPI logging
    if args.verbose > 4:
        verbosity = ["critical",
                     "error",
                     "warn",
                     "info",
                     "debug"][int(min((args.verbose - 4), 4))]
        gphlog = logging.getLogger("graphenebase")
        gphlog.setLevel(getattr(logging, verbosity.upper()))
        gphlog.addHandler(ch)
    if args.verbose > 8:
        verbosity = ["critical",
                     "error",
                     "warn",
                     "info",
                     "debug"][int(min((args.verbose - 8), 4))]
        gphlog = logging.getLogger("grapheneapi")
        gphlog.setLevel(getattr(logging, verbosity.upper()))
        gphlog.addHandler(ch)

    if not hasattr(args, "command"):
        parser.print_help()
        sys.exit(2)

    # initialize STEEM instance
    options = {
        "node": args.node,
        "unsigned": args.unsigned,
        "expires": args.expires
    }
    if args.command == "sign":
        options.update({"offline": True})
    if args.no_wallet:
        options.update({"wif": []})

    steem = stm.Steem(no_broadcast=args.no_broadcast, **options)

    if args.command == "set":
        if (args.key in ["default_account"] and
                    args.value[0] == "@"):
            args.value = args.value[1:]
        configStorage[args.key] = args.value

    elif args.command == "config":
        t = PrettyTable(["Key", "Value"])
        t.align = "l"
        for key in configStorage:
            if key in availableConfigurationKeys:  # hide internal config data
                t.add_row([key, configStorage[key]])
        print(t)

    elif args.command == "info":
        if not args.objects:
            t = PrettyTable(["Key", "Value"])
            t.align = "l"
            blockchain = Blockchain(mode="head")
            info = blockchain.info()
            median_price = steem.get_current_median_history_price()
            steem_per_mvest = (
                Amount(info["total_vesting_fund_steem"]).amount /
                (Amount(info["total_vesting_shares"]).amount / 1e6)
            )
            price = (
                Amount(median_price["base"]).amount /
                Amount(median_price["quote"]).amount
            )
            for key in info:
                t.add_row([key, info[key]])
            t.add_row(["steem per mvest", steem_per_mvest])
            t.add_row(["internal price", price])
            print(t.get_string(sortby="Key"))

        for obj in args.objects:
            # Block
            if re.match("^[0-9]*$", obj):
                block = Block(obj)
                if block:
                    t = PrettyTable(["Key", "Value"])
                    t.align = "l"
                    for key in sorted(block):
                        value = block[key]
                        if key == "transactions":
                            value = json.dumps(value, indent=4)
                        t.add_row([key, value])
                    print(t)
                else:
                    print("Block number %s unknown" % obj)
            # Account name
            elif re.match("^[a-zA-Z0-9\-\._]{2,16}$", obj):
                from math import log10
                account = Account(obj)
                t = PrettyTable(["Key", "Value"])
                t.align = "l"
                for key in sorted(account):
                    value = account[key]
                    if key == "json_metadata":
                        value = json.dumps(
                            json.loads(value or "{}"),
                            indent=4
                        )
                    if key in ["posting",
                               "witness_votes",
                               "active",
                               "owner"]:
                        value = json.dumps(value, indent=4)
                    if key == "reputation" and int(value) > 0:
                        value = int(value)
                        rep = (max(log10(value) - 9, 0) * 9 + 25 if value > 0
                               else max(log10(-value) - 9, 0) * -9 + 25)
                        value = "{:.2f} ({:d})".format(
                            rep, value
                        )
                    t.add_row([key, value])
                print(t)

                # witness available?
                try:
                    witness = Witness(obj)
                    t = PrettyTable(["Key", "Value"])
                    t.align = "l"
                    for key in sorted(witness):
                        value = witness[key]
                        if key in ["props",
                                   "sbd_exchange_rate"]:
                            value = json.dumps(value, indent=4)
                        t.add_row([key, value])
                    print(t)
                except:
                    pass
            # Public Key
            elif re.match("^STM.{48,55}$", obj):
                account = steem.commit.wallet.getAccountFromPublicKey(obj)
                if account:
                    t = PrettyTable(["Account"])
                    t.align = "l"
                    t.add_row([account])
                    print(t)
                else:
                    print("Public Key not known" % obj)
            # Post identifier
            elif re.match(".*@.{3,16}/.*$", obj):
                post = Post(obj)
                if post:
                    t = PrettyTable(["Key", "Value"])
                    t.align = "l"
                    for key in sorted(post):
                        value = post[key]
                        if (key in ["tags",
                                    "json_metadata",
                                    "active_votes"
                                    ]):
                            value = json.dumps(value, indent=4)
                        t.add_row([key, value])
                    print(t)
                else:
                    print("Post now known" % obj)
            else:
                print("Couldn't identify object to read")

    elif args.command == "changewalletpassphrase":
        steem.commit.wallet.changePassphrase()

    elif args.command == "addkey":
        if args.unsafe_import_key:
            for key in args.unsafe_import_key:
                try:
                    steem.commit.wallet.addPrivateKey(key)
                except Exception as e:
                    print(str(e))
        else:
            import getpass
            while True:
                wifkey = getpass.getpass('Private Key (wif) [Enter to quit]:')
                if not wifkey:
                    break
                try:
                    steem.commit.wallet.addPrivateKey(wifkey)
                except Exception as e:
                    print(str(e))
                    continue

                installed_keys = steem.commit.wallet.getPublicKeys()
                if len(installed_keys) == 1:
                    name = steem.commit.wallet.getAccountFromPublicKey(installed_keys[0])
                    print("=" * 30)
                    print("Would you like to make %s a default user?" % name)
                    print()
                    print("You can set it with with:")
                    print("    steempy set default_account <account>")
                    print("=" * 30)

    elif args.command == "delkey":
        if confirm(
                "Are you sure you want to delete keys from your wallet?\n"
                "This step is IRREVERSIBLE! If you don't have a backup, "
                "You may lose access to your account!"
        ):
            for pub in args.pub:
                steem.commit.wallet.removePrivateKeyFromPublicKey(pub)

    elif args.command == "getkey":
        print(steem.commit.wallet.getPrivateKeyForPublicKey(args.pub))

    elif args.command == "listkeys":
        t = PrettyTable(["Available Key"])
        t.align = "l"
        for key in steem.commit.wallet.getPublicKeys():
            t.add_row([key])
        print(t)

    elif args.command == "listaccounts":
        t = PrettyTable(["Name", "Type", "Available Key"])
        t.align = "l"
        for account in steem.commit.wallet.getAccounts():
            t.add_row([
                account["name"] or "n/a",
                account["type"] or "n/a",
                account["pubkey"]
            ])
        print(t)

    elif args.command == "upvote" or args.command == "downvote":
        post = Post(args.post)
        if args.command == "downvote":
            weight = -float(args.weight)
        else:
            weight = +float(args.weight)
        if not args.account:
            print("Not voter provided!")
            return
        print_json(post.vote(weight, voter=args.account))

    elif args.command == "transfer":
        print_json(steem.commit.transfer(
            args.to,
            args.amount,
            args.asset,
            memo=args.memo,
            account=args.account
        ))

    elif args.command == "powerup":
        print_json(steem.commit.transfer_to_vesting(
            args.amount,
            account=args.account,
            to=args.to
        ))

    elif args.command == "powerdown":
        print_json(steem.commit.withdraw_vesting(
            args.amount,
            account=args.account,
        ))

    elif args.command == "convert":
        print_json(steem.commit.convert(
            args.amount,
            account=args.account,
        ))

    elif args.command == "powerdownroute":
        print_json(steem.commit.set_withdraw_vesting_route(
            args.to,
            percentage=args.percentage,
            account=args.account,
            auto_vest=args.auto_vest
        ))

    elif args.command == "balance":
        if args.account and isinstance(args.account, list):
            for account in args.account:
                a = Account(account)

                print("\n@%s" % a.name)
                t = PrettyTable(["Account", "STEEM", "SBD", "VESTS"])
                t.align = "r"
                t.add_row([
                    'Available',
                    a.balances['available']['STEEM'],
                    a.balances['available']['SBD'],
                    a.balances['available']['VESTS'],
                ])
                t.add_row([
                    'Rewards',
                    a.balances['rewards']['STEEM'],
                    a.balances['rewards']['SBD'],
                    a.balances['rewards']['VESTS'],
                ])
                t.add_row([
                    'Savings',
                    a.balances['savings']['STEEM'],
                    a.balances['savings']['SBD'],
                    'N/A',
                ])
                t.add_row([
                    'TOTAL',
                    a.balances['total']['STEEM'],
                    a.balances['total']['SBD'],
                    a.balances['total']['VESTS'],
                ])
                print(t)
        else:
            print("Please specify an account: steempy balance <account>")

    elif args.command == "interest":
        t = PrettyTable(["Account",
                         "Last Interest Payment",
                         "Next Payment",
                         "Interest rate",
                         "Interest"])
        t.align = "r"
        if isinstance(args.account, str):
            args.account = [args.account]
        for a in args.account:
            i = steem.commit.interest(a)

            t.add_row([
                a,
                i["last_payment"],
                "in %s" % strfage(i["next_payment_duration"]),
                "%.1f%%" % i["interest_rate"],
                "%.3f %s" % (i["interest"], "SBD"),
            ])
        print(t)

    elif args.command == "permissions":
        account = Account(args.account)
        print_permissions(account)

    elif args.command == "allow":
        if not args.foreign_account:
            from steembase.account import PasswordKey
            pwd = get_terminal(text="Password for Key Derivation: ", confirm=True)
            args.foreign_account = format(PasswordKey(args.account, pwd, args.permission).get_public(), "STM")
        print_json(steem.commit.allow(
            args.foreign_account,
            weight=args.weight,
            account=args.account,
            permission=args.permission,
            threshold=args.threshold
        ))

    elif args.command == "disallow":
        print_json(steem.commit.disallow(
            args.foreign_account,
            account=args.account,
            permission=args.permission,
            threshold=args.threshold
        ))

    elif args.command == "updatememokey":
        if not args.key:
            # Loop until both match
            from steembase.account import PasswordKey
            pw = get_terminal(text="Password for Memo Key: ", confirm=True, allowedempty=False)
            memo_key = PasswordKey(args.account, pw, "memo")
            args.key = format(memo_key.get_public_key(), "STM")
            memo_privkey = memo_key.get_private_key()
            # Add the key to the wallet
            if not args.no_broadcast:
                steem.commit.wallet.addPrivateKey(memo_privkey)
        print_json(steem.commit.update_memo_key(
            args.key,
            account=args.account
        ))

    elif args.command == "newaccount":
        import getpass
        while True:
            pw = getpass.getpass("New Account Passphrase: ")
            if not pw:
                print("You cannot chosen an empty password!")
                continue
            else:
                pwck = getpass.getpass(
                    "Confirm New Account Passphrase: "
                )
                if pw == pwck:
                    break
                else:
                    print("Given Passphrases do not match!")
        print_json(steem.commit.create_account(
            args.accountname,
            creator=args.account,
            password=pw,
            delegation_fee_steem=args.fee,
        ))

    elif args.command == "importaccount":
        from steembase.account import PasswordKey
        import getpass
        password = getpass.getpass("Account Passphrase: ")
        account = Account(args.account)
        imported = False

        if "owner" in args.roles:
            owner_key = PasswordKey(args.account, password, role="owner")
            owner_pubkey = format(owner_key.get_public_key(), "STM")
            if owner_pubkey in [x[0] for x in account["owner"]["key_auths"]]:
                print("Importing owner key!")
                owner_privkey = owner_key.get_private_key()
                steem.commit.wallet.addPrivateKey(owner_privkey)
                imported = True

        if "active" in args.roles:
            active_key = PasswordKey(args.account, password, role="active")
            active_pubkey = format(active_key.get_public_key(), "STM")
            if active_pubkey in [x[0] for x in account["active"]["key_auths"]]:
                print("Importing active key!")
                active_privkey = active_key.get_private_key()
                steem.commit.wallet.addPrivateKey(active_privkey)
                imported = True

        if "posting" in args.roles:
            posting_key = PasswordKey(args.account, password, role="posting")
            posting_pubkey = format(posting_key.get_public_key(), "STM")
            if posting_pubkey in [x[0] for x in account["posting"]["key_auths"]]:
                print("Importing posting key!")
                posting_privkey = posting_key.get_private_key()
                steem.commit.wallet.addPrivateKey(posting_privkey)
                imported = True

        if "memo" in args.roles:
            memo_key = PasswordKey(args.account, password, role="memo")
            memo_pubkey = format(memo_key.get_public_key(), "STM")
            if memo_pubkey == account["memo_key"]:
                print("Importing memo key!")
                memo_privkey = memo_key.get_private_key()
                steem.commit.wallet.addPrivateKey(memo_privkey)
                imported = True

        if not imported:
            print("No matching key(s) found. Password correct?")

    elif args.command == "sign":
        if args.file and args.file != "-":
            if not os.path.isfile(args.file):
                raise Exception("File %s does not exist!" % args.file)
            with open(args.file) as fp:
                tx = fp.read()
        else:
            tx = sys.stdin.read()
        tx = eval(tx)
        print_json(steem.commit.sign(tx))

    elif args.command == "broadcast":
        if args.file and args.file != "-":
            if not os.path.isfile(args.file):
                raise Exception("File %s does not exist!" % args.file)
            with open(args.file) as fp:
                tx = fp.read()
        else:
            tx = sys.stdin.read()
        tx = eval(tx)
        steem.commit.broadcast(tx)

    elif args.command == "buy":
        if args.asset == "SBD":
            price = 1.0 / args.price
        else:
            price = args.price
        dex = Dex(steem)
        print_json(dex.buy(
            args.amount,
            args.asset,
            price,
            account=args.account
        ))

    elif args.command == "sell":
        if args.asset == "SBD":
            price = 1.0 / args.price
        else:
            price = args.price
        dex = Dex(steem)
        print_json(dex.sell(
            args.amount,
            args.asset,
            price,
            account=args.account
        ))

    elif args.command == "cancel":
        dex = Dex(steem)
        print_json(
            dex.cancel(args.orderid)
        )

    elif args.command == "approvewitness":
        print_json(steem.commit.approve_witness(
            args.witness,
            account=args.account
        ))

    elif args.command == "disapprovewitness":
        print_json(steem.commit.disapprove_witness(
            args.witness,
            account=args.account
        ))

    elif args.command == "resteem":
        print_json(steem.commit.resteem(
            args.identifier,
            account=args.account
        ))

    elif args.command == "follow":
        print_json(steem.commit.follow(
            args.follow,
            what=args.what,
            account=args.account
        ))

    elif args.command == "unfollow":
        print_json(steem.commit.unfollow(
            args.unfollow,
            what=args.what,
            account=args.account
        ))

    elif args.command == "setprofile":
        from .profile import Profile
        keys = []
        values = []
        if args.pair:
            for pair in args.pair:
                key, value = pair.split("=")
                keys.append(key)
                values.append(value)
        if args.variable and args.value:
            keys.append(args.variable)
            values.append(args.value)

        profile = Profile(keys, values)

        account = Account(args.account)
        account["json_metadata"] = Profile(
            account["json_metadata"]
            if account["json_metadata"]
            else {}
        )
        account["json_metadata"].update(profile)

        print_json(steem.commit.update_account_profile(
            account["json_metadata"],
            account=args.account
        ))

    elif args.command == "delprofile":
        from .profile import Profile
        account = Account(args.account)
        account["json_metadata"] = Profile(account["json_metadata"])

        for var in args.variable:
            account["json_metadata"].remove(var)

        print_json(steem.commit.update_account_profile(
            account["json_metadata"],
            account=args.account
        ))

    elif args.command == "witnessupdate":

        witness = Witness(args.witness)
        props = witness["props"]
        if args.account_creation_fee:
            props["account_creation_fee"] = str(Amount("%f STEEM" % args.account_creation_fee))
        if args.maximum_block_size:
            props["maximum_block_size"] = args.maximum_block_size
        if args.sbd_interest_rate:
            props["sbd_interest_rate"] = int(args.sbd_interest_rate * 100)

        print_json(steem.commit.witness_update(
            args.signing_key or witness["signing_key"],
            args.url or witness["url"],
            props,
            account=args.witness
        ))

    elif args.command == "witnesscreate":
        props = {
            "account_creation_fee": str(Amount("%f STEEM" % args.account_creation_fee)),
            "maximum_block_size": args.maximum_block_size,
            "sbd_interest_rate": int(args.sbd_interest_rate * 100)
        }
        print_json(steem.commit.witness_update(
            args.signing_key,
            args.url,
            props,
            account=args.witness
        ))

    else:
        print("No valid command given")
Exemplo n.º 7
0
from steembase.account import PasswordKey

account = 'initminer'
password = '******'
key_types = ['posting', 'active', 'owner', 'memo']

for key_type in key_types:
    private_key = PasswordKey(account, password, key_type).get_private_key()
    public_key = private_key.pubkey

    print('Private ' + key_type + ' key: ' + str(private_key))
    print('Public ' + key_type + ' key: ' + str(public_key) + '\n')
Exemplo n.º 8
0
    def create_account(
        self,
        account_name,
        json_meta={},
        creator=None,
        owner_key=None,
        active_key=None,
        posting_key=None,
        memo_key=None,
        password=None,
        additional_owner_keys=[],
        additional_active_keys=[],
        additional_posting_keys=[],
        additional_owner_accounts=[],
        additional_active_accounts=[],
        additional_posting_accounts=[],
        storekeys=True,
    ):
        """ Create new account in Steem

            The brainkey/password can be used to recover all generated keys (see
            `steembase.account` for more details.

            By default, this call will use ``default_author`` to
            register a new name ``account_name`` with all keys being
            derived from a new brain key that will be returned. The
            corresponding keys will automatically be installed in the
            wallet.

            .. note:: Account creations cost a fee that is defined by
                       the network. If you create an account, you will
                       need to pay for that fee!

            .. warning:: Don't call this method unless you know what
                          you are doing! Be sure to understand what this
                          method does and where to find the private keys
                          for your account.

            .. note:: Please note that this imports private keys
                      (if password is present) into the wallet by
                      default. However, it **does not import the owner
                      key** for security reasons. Do NOT expect to be
                      able to recover it from piston if you lose your
                      password!

            :param str account_name: (**required**) new account name
            :param str json_meta: Optional meta data for the account
            :param str creator: which account should pay the registration fee
                                (defaults to ``default_author``)
            :param str owner_key: Main owner key
            :param str active_key: Main active key
            :param str posting_key: Main posting key
            :param str memo_key: Main memo_key
            :param str password: Alternatively to providing keys, one
                                 can provide a password from which the
                                 keys will be derived
            :param array additional_owner_keys:  Additional owner public keys
            :param array additional_active_keys: Additional active public keys
            :param array additional_posting_keys: Additional posting public keys
            :param array additional_owner_accounts: Additional owner account names
            :param array additional_active_accounts: Additional acctive account names
            :param array additional_posting_accounts: Additional posting account names
            :param bool storekeys: Store new keys in the wallet (default: ``True``)
            :raises AccountExistsException: if the account already exists on the blockchain

        """
        if not creator and config["default_author"]:
            creator = config["default_author"]
        if not creator:
            raise ValueError("Not creator account given. Define it with " +
                             "creator=x, or set the default_author in piston")
        if password and (owner_key or posting_key or active_key or memo_key):
            raise ValueError("You cannot use 'password' AND provide keys!")

        account = None
        try:
            account = self.rpc.get_account(account_name)
        except:
            pass
        if account:
            raise AccountExistsException

        " Generate new keys from password"
        from steembase.account import PasswordKey, PublicKey
        if password:
            posting_key = PasswordKey(account_name, password, role="posting")
            active_key = PasswordKey(account_name, password, role="active")
            owner_key = PasswordKey(account_name, password, role="owner")
            memo_key = PasswordKey(account_name, password, role="memo")
            posting_pubkey = posting_key.get_public_key()
            active_pubkey = active_key.get_public_key()
            owner_pubkey = owner_key.get_public_key()
            memo_pubkey = memo_key.get_public_key()
            posting_privkey = posting_key.get_private_key()
            active_privkey = active_key.get_private_key()
            # owner_privkey   = owner_key.get_private_key()
            memo_privkey = memo_key.get_private_key()
            # store private keys
            if storekeys:
                # self.wallet.addPrivateKey(owner_privkey)
                self.wallet.addPrivateKey(active_privkey)
                self.wallet.addPrivateKey(posting_privkey)
                self.wallet.addPrivateKey(memo_privkey)
        elif (owner_key and posting_key and active_key and memo_key):
            posting_pubkey = PublicKey(posting_key, prefix=prefix)
            active_pubkey = PublicKey(active_key, prefix=prefix)
            owner_pubkey = PublicKey(owner_key, prefix=prefix)
            memo_pubkey = PublicKey(memo_key, prefix=prefix)
        else:
            raise ValueError(
                "Call incomplete! Provide either a password or public keys!")

        owner = format(posting_pubkey, prefix)
        active = format(active_pubkey, prefix)
        posting = format(owner_pubkey, prefix)
        memo = format(memo_pubkey, prefix)

        owner_key_authority = [[owner, 1]]
        active_key_authority = [[active, 1]]
        posting_key_authority = [[posting, 1]]
        owner_accounts_authority = []
        active_accounts_authority = []
        posting_accounts_authority = []

        # additional authorities
        for k in additional_owner_keys:
            owner_key_authority.append([k, 1])
        for k in additional_active_keys:
            active_key_authority.append([k, 1])
        for k in additional_posting_keys:
            posting_key_authority.append([k, 1])

        for k in additional_owner_accounts:
            owner_accounts_authority.append([k, 1])
        for k in additional_active_accounts:
            active_accounts_authority.append([k, 1])
        for k in additional_posting_accounts:
            posting_accounts_authority.append([k, 1])

        props = self.rpc.get_chain_properties()
        fee = props["account_creation_fee"]
        s = {
            'creator': creator,
            'fee': fee,
            'json_metadata': json_meta,
            'memo_key': memo,
            'new_account_name': account_name,
            'owner': {
                'account_auths': owner_accounts_authority,
                'key_auths': owner_key_authority,
                'weight_threshold': 1
            },
            'active': {
                'account_auths': active_accounts_authority,
                'key_auths': active_key_authority,
                'weight_threshold': 1
            },
            'posting': {
                'account_auths': posting_accounts_authority,
                'key_auths': posting_key_authority,
                'weight_threshold': 1
            }
        }
        op = transactions.Account_create(**s)
        wif = self.wallet.getActiveKeyForAccount(creator)
        return self.executeOp(op, wif)
Exemplo n.º 9
0
def legacyentry():
    """
    Piston like cli application.
    This will be re-written as a @click app in the future.
    """
    global args

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description="Command line tool to interact with the Steem network")
    """
        Default settings for all tools
    """
    parser.add_argument(
        '--node',
        type=str,
        default=configStorage["node"],
        help='URL for public Steem API (default: "https://api.steemit.com")'
    )

    parser.add_argument(
        '--no-broadcast',
        '-d',
        action='store_true',
        help='Do not broadcast anything')
    parser.add_argument(
        '--no-wallet',
        '-p',
        action='store_true',
        help='Do not load the wallet')
    parser.add_argument(
        '--unsigned',
        '-x',
        action='store_true',
        help='Do not try to sign the transaction')
    parser.add_argument(
        '--expires',
        '-e',
        default=60,
        help='Expiration time in seconds (defaults to 30)')
    parser.add_argument(
        '--verbose', '-v', type=int, default=3, help='Verbosity')
    parser.add_argument(
        '--version',
        action='version',
        version='%(prog)s {version}'.format(
            version=pkg_resources.require("steem")[0].version))

    subparsers = parser.add_subparsers(help='sub-command help')
    """
        Command "set"
    """
    setconfig = subparsers.add_parser('set', help='Set configuration')
    setconfig.add_argument(
        'key',
        type=str,
        choices=availableConfigurationKeys,
        help='Configuration key')
    setconfig.add_argument('value', type=str, help='Configuration value')
    setconfig.set_defaults(command="set")
    """
        Command "config"
    """
    configconfig = subparsers.add_parser(
        'config', help='Show local configuration')
    configconfig.set_defaults(command="config")
    """
        Command "info"
    """
    parser_info = subparsers.add_parser(
        'info', help='Show basic STEEM blockchain info')
    parser_info.set_defaults(command="info")
    parser_info.add_argument(
        'objects',
        nargs='*',
        type=str,
        help='General information about the blockchain, a block, an account'
             ' name, a post, a public key, ...')
    """
        Command "changewalletpassphrase"
    """
    changepasswordconfig = subparsers.add_parser(
        'changewalletpassphrase', help='Change wallet password')
    changepasswordconfig.set_defaults(command="changewalletpassphrase")
    """
        Command "addkey"
    """
    addkey = subparsers.add_parser(
        'addkey', help='Add a new key to the wallet')
    addkey.add_argument(
        '--unsafe-import-key',
        nargs='*',
        type=str,
        help='private key to import into the wallet (unsafe, unless you ' +
             'delete your shell history)')
    addkey.set_defaults(command="addkey")

    parsewif = subparsers.add_parser(
        'parsewif', help='Parse a WIF private key without importing')
    parsewif.add_argument(
        '--unsafe-import-key',
        nargs='*',
        type=str,
        help='WIF key to parse (unsafe, delete your bash history)')
    parsewif.set_defaults(command='parsewif')
    """
        Command "delkey"
    """
    delkey = subparsers.add_parser(
        'delkey', help='Delete keys from the wallet')
    delkey.add_argument(
        'pub',
        nargs='*',
        type=str,
        help='the public key to delete from the wallet')
    delkey.set_defaults(command="delkey")
    """
        Command "getkey"
    """
    getkey = subparsers.add_parser(
        'getkey', help='Dump the privatekey of a pubkey from the wallet')
    getkey.add_argument(
        'pub',
        type=str,
        help='the public key for which to show the private key')
    getkey.set_defaults(command="getkey")
    """
        Command "listkeys"
    """
    listkeys = subparsers.add_parser(
        'listkeys', help='List available keys in your wallet')
    listkeys.set_defaults(command="listkeys")
    """
        Command "listaccounts"
    """
    listaccounts = subparsers.add_parser(
        'listaccounts', help='List available accounts in your wallet')
    listaccounts.set_defaults(command="listaccounts")
    """
        Command "upvote"
    """
    parser_upvote = subparsers.add_parser('upvote', help='Upvote a post')
    parser_upvote.set_defaults(command="upvote")
    parser_upvote.add_argument(
        'post',
        type=str,
        help='author/permlink-identifier of the post to upvote ' +
             'to (e.g. xeroc/python-steem-0-1)')
    parser_upvote.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='The voter account name')
    parser_upvote.add_argument(
        '--weight',
        type=float,
        default=configStorage["default_vote_weight"],
        required=False,
        help='Actual weight (from 0.1 to 100.0)')
    """
        Command "downvote"
    """
    parser_downvote = subparsers.add_parser('downvote', help='Downvote a post')
    parser_downvote.set_defaults(command="downvote")
    parser_downvote.add_argument(
        '--account',
        type=str,
        default=configStorage["default_account"],
        help='The voter account name')
    parser_downvote.add_argument(
        'post',
        type=str,
        help='author/permlink-identifier of the post to downvote ' +
             'to (e.g. xeroc/python-steem-0-1)')
    parser_downvote.add_argument(
        '--weight',
        type=float,
        default=configStorage["default_vote_weight"],
        required=False,
        help='Actual weight (from 0.1 to 100.0)')
    """
        Command "transfer"
    """
    parser_transfer = subparsers.add_parser('transfer', help='Transfer STEEM')
    parser_transfer.set_defaults(command="transfer")
    parser_transfer.add_argument('to', type=str, help='Recipient')
    parser_transfer.add_argument(
        'amount', type=float, help='Amount to transfer')
    parser_transfer.add_argument(
        'asset',
        type=str,
        choices=["STEEM", "SBD"],
        help='Asset to transfer (i.e. STEEM or SDB)')
    parser_transfer.add_argument(
        'memo', type=str, nargs="?", default="", help='Optional memo')
    parser_transfer.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Transfer from this account')
    """
        Command "powerup"
    """
    parser_powerup = subparsers.add_parser(
        'powerup', help='Power up (vest STEEM as STEEM POWER)')
    parser_powerup.set_defaults(command="powerup")
    parser_powerup.add_argument(
        'amount', type=str, help='Amount of VESTS to powerup')
    parser_powerup.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Powerup from this account')
    parser_powerup.add_argument(
        '--to',
        type=str,
        required=False,
        default=None,
        help='Powerup this account')
    """
        Command "powerdown"
    """
    parser_powerdown = subparsers.add_parser(
        'powerdown',
        help='Power down (start withdrawing STEEM from steem POWER)')
    parser_powerdown.set_defaults(command="powerdown")
    parser_powerdown.add_argument(
        'amount', type=str, help='Amount of VESTS to powerdown')
    parser_powerdown.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='powerdown from this account')
    """
        Command "powerdownroute"
    """
    parser_powerdownroute = subparsers.add_parser(
        'powerdownroute', help='Setup a powerdown route')
    parser_powerdownroute.set_defaults(command="powerdownroute")
    parser_powerdownroute.add_argument(
        'to',
        type=str,
        default=configStorage["default_account"],
        help='The account receiving either VESTS/SteemPower or STEEM.')
    parser_powerdownroute.add_argument(
        '--percentage',
        type=float,
        default=100,
        help='The percent of the withdraw to go to the "to" account')
    parser_powerdownroute.add_argument(
        '--account',
        type=str,
        default=configStorage["default_account"],
        help='The account which is powering down')
    parser_powerdownroute.add_argument(
        '--auto_vest',
        action='store_true',
        help=('Set to true if the from account should receive the VESTS as'
              'VESTS, or false if it should receive them as STEEM.'))
    """
        Command "convert"
    """
    parser_convert = subparsers.add_parser(
        'convert',
        help='Convert STEEMDollars to Steem (takes a week to settle)')
    parser_convert.set_defaults(command="convert")
    parser_convert.add_argument(
        'amount', type=float, help='Amount of SBD to convert')
    parser_convert.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Convert from this account')
    """
        Command "balance"
    """
    parser_balance = subparsers.add_parser(
        'balance', help='Show the balance of one more more accounts')
    parser_balance.set_defaults(command="balance")
    parser_balance.add_argument(
        'account',
        type=str,
        nargs="*",
        default=configStorage["default_account"],
        help='balance of these account (multiple accounts allowed)')
    """
        Command "interest"
    """
    interest = subparsers.add_parser(
        'interest', help='Get information about interest payment')
    interest.set_defaults(command="interest")
    interest.add_argument(
        'account',
        type=str,
        nargs="*",
        default=configStorage["default_account"],
        help='Inspect these accounts')
    """
        Command "permissions"
    """
    parser_permissions = subparsers.add_parser(
        'permissions', help='Show permissions of an account')
    parser_permissions.set_defaults(command="permissions")
    parser_permissions.add_argument(
        'account',
        type=str,
        nargs="?",
        default=configStorage["default_account"],
        help='Account to show permissions for')
    """
        Command "allow"
    """
    parser_allow = subparsers.add_parser(
        'allow', help='Allow an account/key to interact with your account')
    parser_allow.set_defaults(command="allow")
    parser_allow.add_argument(
        '--account',
        type=str,
        nargs="?",
        default=configStorage["default_account"],
        help='The account to allow action for')
    parser_allow.add_argument(
        'foreign_account',
        type=str,
        nargs="?",
        help='The account or key that will be allowed to interact with ' +
             'your account')
    parser_allow.add_argument(
        '--permission',
        type=str,
        default="posting",
        choices=["owner", "posting", "active"],
        help='The permission to grant (defaults to "posting")')
    parser_allow.add_argument(
        '--weight',
        type=int,
        default=None,
        help=('The weight to use instead of the (full) threshold. '
              'If the weight is smaller than the threshold, '
              'additional signatures are required'))
    parser_allow.add_argument(
        '--threshold',
        type=int,
        default=None,
        help=('The permission\'s threshold that needs to be reached '
              'by signatures to be able to interact'))
    """
        Command "disallow"
    """
    parser_disallow = subparsers.add_parser(
        'disallow',
        help='Remove allowance an account/key to interact with your account')
    parser_disallow.set_defaults(command="disallow")
    parser_disallow.add_argument(
        '--account',
        type=str,
        nargs="?",
        default=configStorage["default_account"],
        help='The account to disallow action for')
    parser_disallow.add_argument(
        'foreign_account',
        type=str,
        help='The account or key whose allowance to interact as your ' +
             'account will be removed')
    parser_disallow.add_argument(
        '--permission',
        type=str,
        default="posting",
        choices=["owner", "posting", "active"],
        help='The permission to remove (defaults to "posting")')
    parser_disallow.add_argument(
        '--threshold',
        type=int,
        default=None,
        help=('The permission\'s threshold that needs to be reached '
              'by signatures to be able to interact'))
    """
        Command "newaccount"
    """
    parser_newaccount = subparsers.add_parser(
        'newaccount', help='Create a new account')
    parser_newaccount.set_defaults(command="newaccount")
    parser_newaccount.add_argument(
        'accountname', type=str, help='New account name')
    parser_newaccount.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Account that pays the fee')
    parser_newaccount.add_argument(
        '--fee',
        type=str,
        required=False,
        default='0 STEEM',
        help='Base Fee to pay. Delegate the rest.')
    """
        Command "importaccount"
    """
    parser_importaccount = subparsers.add_parser(
        'importaccount', help='Import an account using a passphrase')
    parser_importaccount.set_defaults(command="importaccount")
    parser_importaccount.add_argument('account', type=str, help='Account name')
    parser_importaccount.add_argument(
        '--roles',
        type=str,
        nargs="*",
        default=["active", "posting", "memo"],  # no owner
        help='Import specified keys (owner, active, posting, memo)')
    """
        Command "updateMemoKey"
    """
    parser_updateMemoKey = subparsers.add_parser(
        'updatememokey', help='Update an account\'s memo key')
    parser_updateMemoKey.set_defaults(command="updatememokey")
    parser_updateMemoKey.add_argument(
        '--account',
        type=str,
        nargs="?",
        default=configStorage["default_account"],
        help='The account to updateMemoKey action for')
    parser_updateMemoKey.add_argument(
        '--key', type=str, default=None, help='The new memo key')
    """
        Command "approvewitness"
    """
    parser_approvewitness = subparsers.add_parser(
        'approvewitness', help='Approve a witnesses')
    parser_approvewitness.set_defaults(command="approvewitness")
    parser_approvewitness.add_argument(
        'witness', type=str, help='Witness to approve')
    parser_approvewitness.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Your account')
    """
        Command "disapprovewitness"
    """
    parser_disapprovewitness = subparsers.add_parser(
        'disapprovewitness', help='Disapprove a witnesses')
    parser_disapprovewitness.set_defaults(command="disapprovewitness")
    parser_disapprovewitness.add_argument(
        'witness', type=str, help='Witness to disapprove')
    parser_disapprovewitness.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Your account')
    """
        Command "sign"
    """
    parser_sign = subparsers.add_parser(
        'sign',
        help='Sign a provided transaction with available and required keys')
    parser_sign.set_defaults(command="sign")
    parser_sign.add_argument(
        '--file',
        type=str,
        required=False,
        help='Load transaction from file. If "-", read from ' +
             'stdin (defaults to "-")')
    """
        Command "broadcast"
    """
    parser_broadcast = subparsers.add_parser(
        'broadcast', help='broadcast a signed transaction')
    parser_broadcast.set_defaults(command="broadcast")
    parser_broadcast.add_argument(
        '--file',
        type=str,
        required=False,
        help='Load transaction from file. If "-", read from ' +
             'stdin (defaults to "-")')
    """
        Command "orderbook"
    """
    orderbook = subparsers.add_parser(
        'orderbook', help='Obtain orderbook of the internal market')
    orderbook.set_defaults(command="orderbook")
    orderbook.add_argument(
        '--chart',
        action='store_true',
        help="Enable charting (requires matplotlib)")
    """
        Command "buy"
    """
    parser_buy = subparsers.add_parser(
        'buy', help='Buy STEEM or SBD from the internal market')
    parser_buy.set_defaults(command="buy")
    parser_buy.add_argument('amount', type=float, help='Amount to buy')
    parser_buy.add_argument(
        'asset',
        type=str,
        choices=["STEEM", "SBD"],
        help='Asset to buy (i.e. STEEM or SDB)')
    parser_buy.add_argument(
        'price', type=float, help='Limit buy price denoted in (SBD per STEEM)')
    parser_buy.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Buy with this account (defaults to "default_account")')
    """
        Command "sell"
    """
    parser_sell = subparsers.add_parser(
        'sell', help='Sell STEEM or SBD from the internal market')
    parser_sell.set_defaults(command="sell")
    parser_sell.add_argument('amount', type=float, help='Amount to sell')
    parser_sell.add_argument(
        'asset',
        type=str,
        choices=["STEEM", "SBD"],
        help='Asset to sell (i.e. STEEM or SDB)')
    parser_sell.add_argument(
        'price',
        type=float,
        help='Limit sell price denoted in (SBD per STEEM)')
    parser_sell.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Sell from this account (defaults to "default_account")')
    """
        Command "cancel"
    """
    parser_cancel = subparsers.add_parser(
        'cancel', help='Cancel order in the internal market')
    parser_cancel.set_defaults(command="cancel")
    parser_cancel.add_argument('orderid', type=int, help='Orderid')
    parser_cancel.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Cancel from this account (defaults to "default_account")')
    """
        Command "resteem"
    """
    parser_resteem = subparsers.add_parser(
        'resteem', help='Resteem an existing post')
    parser_resteem.set_defaults(command="resteem")
    parser_resteem.add_argument(
        'identifier',
        type=str,
        help='author/permlink-identifier of the post to resteem')
    parser_resteem.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Resteem as this user (requires to have the ' +
             'key installed in the wallet)')
    """
        Command "follow"
    """
    parser_follow = subparsers.add_parser(
        'follow', help='Follow another account')
    parser_follow.set_defaults(command="follow")
    parser_follow.add_argument('follow', type=str, help='Account to follow')
    parser_follow.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Follow from this account')
    parser_follow.add_argument(
        '--what',
        type=str,
        required=False,
        nargs="*",
        default=["blog"],
        help='Follow these objects (defaults to "blog")')
    """
        Command "unfollow"
    """
    parser_unfollow = subparsers.add_parser(
        'unfollow', help='unfollow another account')
    parser_unfollow.set_defaults(command="unfollow")
    parser_unfollow.add_argument(
        'unfollow', type=str, help='Account to unfollow')
    parser_unfollow.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='Unfollow from this account')
    parser_unfollow.add_argument(
        '--what',
        type=str,
        required=False,
        nargs="*",
        default=[],
        help='Unfollow these objects (defaults to "blog")')
    """
        Command "setprofile"
    """
    parser_setprofile = subparsers.add_parser(
        'setprofile', help='Set a variable in an account\'s profile')
    parser_setprofile.set_defaults(command="setprofile")
    parser_setprofile.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='setprofile as this user (requires to have the key ' +
             'installed in the wallet)')
    parser_setprofile_a = parser_setprofile.add_argument_group(
        'Multiple keys at once')
    parser_setprofile_a.add_argument(
        '--pair', type=str, nargs='*', help='"Key=Value" pairs')
    parser_setprofile_b = parser_setprofile.add_argument_group(
        'Just a single key')
    parser_setprofile_b.add_argument(
        'variable', type=str, nargs='?', help='Variable to set')
    parser_setprofile_b.add_argument(
        'value', type=str, nargs='?', help='Value to set')
    """
        Command "delprofile"
    """
    parser_delprofile = subparsers.add_parser(
        'delprofile', help='Set a variable in an account\'s profile')
    parser_delprofile.set_defaults(command="delprofile")
    parser_delprofile.add_argument(
        '--account',
        type=str,
        required=False,
        default=configStorage["default_account"],
        help='delprofile as this user (requires to have the ' +
             'key installed in the wallet)')
    parser_delprofile.add_argument(
        'variable', type=str, nargs='*', help='Variable to set')
    """
        Command "witnessupdate"
    """
    parser_witnessprops = subparsers.add_parser(
        'witnessupdate', help='Change witness properties')
    parser_witnessprops.set_defaults(command="witnessupdate")
    parser_witnessprops.add_argument(
        '--witness',
        type=str,
        default=configStorage["default_account"],
        help='Witness name')
    parser_witnessprops.add_argument(
        '--maximum_block_size',
        type=float,
        required=False,
        help='Max block size')
    parser_witnessprops.add_argument(
        '--account_creation_fee',
        type=float,
        required=False,
        help='Account creation fee')
    parser_witnessprops.add_argument(
        '--sbd_interest_rate',
        type=float,
        required=False,
        help='SBD interest rate in percent')
    parser_witnessprops.add_argument(
        '--url', type=str, required=False, help='Witness URL')
    parser_witnessprops.add_argument(
        '--signing_key', type=str, required=False, help='Signing Key')
    """
        Command "witnesscreate"
    """
    parser_witnesscreate = subparsers.add_parser(
        'witnesscreate', help='Create a witness')
    parser_witnesscreate.set_defaults(command="witnesscreate")
    parser_witnesscreate.add_argument('witness', type=str, help='Witness name')
    parser_witnesscreate.add_argument(
        'signing_key', type=str, help='Signing Key')
    parser_witnesscreate.add_argument(
        '--maximum_block_size',
        type=float,
        default="65536",
        help='Max block size')
    parser_witnesscreate.add_argument(
        '--account_creation_fee',
        type=float,
        default=30,
        help='Account creation fee')
    parser_witnesscreate.add_argument(
        '--sbd_interest_rate',
        type=float,
        default=0.0,
        help='SBD interest rate in percent')
    parser_witnesscreate.add_argument(
        '--url', type=str, default="", help='Witness URL')
    """
        Parse Arguments
    """
    args = parser.parse_args()

    # Logging
    log = logging.getLogger(__name__)
    verbosity = ["critical", "error", "warn", "info", "debug"][int(
        min(args.verbose, 4))]
    log.setLevel(getattr(logging, verbosity.upper()))
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    ch = logging.StreamHandler()
    ch.setLevel(getattr(logging, verbosity.upper()))
    ch.setFormatter(formatter)
    log.addHandler(ch)

    # GrapheneAPI logging
    if args.verbose > 4:
        verbosity = ["critical", "error", "warn", "info", "debug"][int(
            min((args.verbose - 4), 4))]
        gphlog = logging.getLogger("graphenebase")
        gphlog.setLevel(getattr(logging, verbosity.upper()))
        gphlog.addHandler(ch)
    if args.verbose > 8:
        verbosity = ["critical", "error", "warn", "info", "debug"][int(
            min((args.verbose - 8), 4))]
        gphlog = logging.getLogger("grapheneapi")
        gphlog.setLevel(getattr(logging, verbosity.upper()))
        gphlog.addHandler(ch)

    if not hasattr(args, "command"):
        parser.print_help()
        sys.exit(2)

    # initialize STEEM instance
    options = {
        "node": args.node,
        "unsigned": args.unsigned,
        "expires": args.expires
    }
    if args.command == "sign":
        options.update({"offline": True})
    if args.no_wallet:
        options.update({"wif": []})

    steem = stm.Steem(no_broadcast=args.no_broadcast, **options)

    if args.command == "set":
        # TODO: Evaluate this line with cli refactor.
        if (args.key in ["default_account"] and args.value[0] == "@"):
            args.value = args.value[1:]
        configStorage[args.key] = args.value

    elif args.command == "config":
        t = PrettyTable(["Key", "Value"])
        t.align = "l"
        for key in configStorage:
            # hide internal config data
            if key in availableConfigurationKeys:
                t.add_row([key, configStorage[key]])
        print(t)

    elif args.command == "info":
        if not args.objects:
            t = PrettyTable(["Key", "Value"])
            t.align = "l"
            blockchain = Blockchain(mode="head")
            info = blockchain.info()
            median_price = steem.get_current_median_history_price()
            steem_per_mvest = (
                    Amount(info["total_vesting_fund_steem"]).amount /
                    (Amount(info["total_vesting_shares"]).amount / 1e6))
            price = (Amount(median_price["base"]).amount / Amount(
                median_price["quote"]).amount)
            for key in info:
                t.add_row([key, info[key]])
            t.add_row(["steem per mvest", steem_per_mvest])
            t.add_row(["internal price", price])
            print(t.get_string(sortby="Key"))

        for obj in args.objects:
            # Block
            if re.match("^[0-9]*$", obj):
                block = Block(obj)
                if block:
                    t = PrettyTable(["Key", "Value"])
                    t.align = "l"
                    for key in sorted(block):
                        value = block[key]
                        if key == "transactions":
                            value = json.dumps(value, indent=4)
                        t.add_row([key, value])
                    print(t)
                else:
                    print("Block number %s unknown" % obj)
            # Account name
            elif re.match("^[a-zA-Z0-9\-\._]{2,16}$", obj):
                from math import log10
                account = Account(obj)
                t = PrettyTable(["Key", "Value"])
                t.align = "l"
                for key in sorted(account):
                    value = account[key]
                    if key == "json_metadata":
                        value = json.dumps(json.loads(value or "{}"), indent=4)
                    if key in ["posting", "witness_votes", "active", "owner"]:
                        value = json.dumps(value, indent=4)
                    if key == "reputation" and int(value) > 0:
                        value = int(value)
                        rep = (max(log10(value) - 9, 0) * 9 + 25 if value > 0
                               else max(log10(-value) - 9, 0) * -9 + 25)
                        value = "{:.2f} ({:d})".format(rep, value)
                    t.add_row([key, value])
                print(t)

                # witness available?
                try:
                    witness = Witness(obj)
                    t = PrettyTable(["Key", "Value"])
                    t.align = "l"
                    for key in sorted(witness):
                        value = witness[key]
                        if key in ["props", "sbd_exchange_rate"]:
                            value = json.dumps(value, indent=4)
                        t.add_row([key, value])
                    print(t)
                except:  # noqa FIXME(sneak)
                    pass
            # Public Key
            elif re.match("^STM.{48,55}$", obj):
                account = steem.commit.wallet.getAccountFromPublicKey(obj)
                if account:
                    t = PrettyTable(["Account"])
                    t.align = "l"
                    t.add_row([account])
                    print(t)
                else:
                    print("Public Key not known" % obj)
            # Post identifier
            elif re.match(".*@.{3,16}/.*$", obj):
                post = Post(obj)
                if post:
                    t = PrettyTable(["Key", "Value"])
                    t.align = "l"
                    for key in sorted(post):
                        value = post[key]
                        if (key in ["tags", "json_metadata", "active_votes"]):
                            value = json.dumps(value, indent=4)
                        t.add_row([key, value])
                    print(t)
                else:
                    print("Post now known" % obj)
            else:
                print("Couldn't identify object to read")

    elif args.command == "changewalletpassphrase":
        steem.commit.wallet.changePassphrase()

    elif args.command == "addkey":
        if args.unsafe_import_key:
            for key in args.unsafe_import_key:
                try:
                    steem.commit.wallet.addPrivateKey(key)
                except Exception as e:
                    print(str(e))
        else:
            import getpass
            while True:
                wifkey = getpass.getpass('Private Key (wif) [Enter to quit]:')
                if not wifkey:
                    break
                try:
                    steem.commit.wallet.addPrivateKey(wifkey)
                except Exception as e:
                    print(str(e))
                    continue

                installed_keys = steem.commit.wallet.getPublicKeys()
                if len(installed_keys) == 1:
                    name = steem.commit.wallet.getAccountFromPublicKey(
                        installed_keys[0])
                    print("=" * 30)
                    print("Would you like to make %s a default user?" % name)
                    print()
                    print("You can set it with with:")
                    print("    steempy set default_account <account>")
                    print("=" * 30)

    elif args.command == "delkey":
        if confirm("Are you sure you want to delete keys from your wallet?\n"
                   "This step is IRREVERSIBLE! If you don't have a backup, "
                   "You may lose access to your account!"):
            for pub in args.pub:
                steem.commit.wallet.removePrivateKeyFromPublicKey(pub)

    elif args.command == "parsewif":
        if args.unsafe_import_key:
            for key in args.unsafe_import_key:
                try:
                    print(PrivateKey(key).pubkey)
                except Exception as e:
                    print(str(e))
        else:
            import getpass
            while True:
                wifkey = getpass.getpass('Private Key (wif) [Enter to quit:')
                if not wifkey:
                    break
                try:
                    print(PrivateKey(wifkey).pubkey)
                except Exception as e:
                    print(str(e))
                    continue
    elif args.command == "getkey":
        print(steem.commit.wallet.getPrivateKeyForPublicKey(args.pub))

    elif args.command == "listkeys":
        t = PrettyTable(["Available Key"])
        t.align = "l"
        for key in steem.commit.wallet.getPublicKeys():
            t.add_row([key])
        print(t)

    elif args.command == "listaccounts":
        t = PrettyTable(["Name", "Type", "Available Key"])
        t.align = "l"
        for account in steem.commit.wallet.getAccounts():
            t.add_row([
                account["name"] or "n/a", account["type"] or "n/a",
                account["pubkey"]
            ])
        print(t)

    elif args.command == "upvote" or args.command == "downvote":
        post = Post(args.post)
        if args.command == "downvote":
            weight = -float(args.weight)
        else:
            weight = +float(args.weight)
        if not args.account:
            print("Not voter provided!")
            return
        print_json(post.vote(weight, voter=args.account))

    elif args.command == "transfer":
        print_json(
            steem.commit.transfer(
                args.to,
                args.amount,
                args.asset,
                memo=args.memo,
                account=args.account))

    elif args.command == "powerup":
        print_json(
            steem.commit.transfer_to_vesting(
                args.amount, account=args.account, to=args.to))

    elif args.command == "powerdown":
        print_json(
            steem.commit.withdraw_vesting(
                args.amount,
                account=args.account,
            ))

    elif args.command == "convert":
        print_json(steem.commit.convert(
            args.amount,
            account=args.account,
        ))

    elif args.command == "powerdownroute":
        print_json(
            steem.commit.set_withdraw_vesting_route(
                args.to,
                percentage=args.percentage,
                account=args.account,
                auto_vest=args.auto_vest))

    elif args.command == "balance":
        if args.account and isinstance(args.account, list):
            for account in args.account:
                a = Account(account)

                print("\n%s" % a.name)
                t = PrettyTable(["Account", "STEEM", "SBD", "VESTS"])
                t.align = "r"
                t.add_row([
                    'Available',
                    a.balances['available']['STEEM'],
                    a.balances['available']['SBD'],
                    a.balances['available']['VESTS'],
                ])
                t.add_row([
                    'Rewards',
                    a.balances['rewards']['STEEM'],
                    a.balances['rewards']['SBD'],
                    a.balances['rewards']['VESTS'],
                ])
                t.add_row([
                    'Savings',
                    a.balances['savings']['STEEM'],
                    a.balances['savings']['SBD'],
                    'N/A',
                ])
                t.add_row([
                    'TOTAL',
                    a.balances['total']['STEEM'],
                    a.balances['total']['SBD'],
                    a.balances['total']['VESTS'],
                ])
                print(t)
        else:
            print("Please specify an account: steempy balance <account>")

    elif args.command == "interest":
        t = PrettyTable([
            "Account", "Last Interest Payment", "Next Payment",
            "Interest rate", "Interest"
        ])
        t.align = "r"
        if isinstance(args.account, str):
            args.account = [args.account]
        for a in args.account:
            i = steem.commit.interest(a)

            t.add_row([
                a,
                i["last_payment"],
                "in %s" % strfage(i["next_payment_duration"]),
                "%.1f%%" % i["interest_rate"],
                "%.3f %s" % (i["interest"], "SBD"),
            ])
        print(t)

    elif args.command == "permissions":
        account = Account(args.account)
        print_permissions(account)

    elif args.command == "allow":
        if not args.foreign_account:
            from steembase.account import PasswordKey
            pwd = get_terminal(
                text="Password for Key Derivation: ", confirm=True)
            args.foreign_account = format(
                PasswordKey(args.account, pwd, args.permission).get_public(),
                "STM")
        print_json(
            steem.commit.allow(
                args.foreign_account,
                weight=args.weight,
                account=args.account,
                permission=args.permission,
                threshold=args.threshold))

    elif args.command == "disallow":
        print_json(
            steem.commit.disallow(
                args.foreign_account,
                account=args.account,
                permission=args.permission,
                threshold=args.threshold))

    elif args.command == "updatememokey":
        if not args.key:
            # Loop until both match
            from steembase.account import PasswordKey
            pw = get_terminal(
                text="Password for Memo Key: ",
                confirm=True,
                allowedempty=False)
            memo_key = PasswordKey(args.account, pw, "memo")
            args.key = format(memo_key.get_public_key(), "STM")
            memo_privkey = memo_key.get_private_key()
            # Add the key to the wallet
            if not args.no_broadcast:
                steem.commit.wallet.addPrivateKey(memo_privkey)
        print_json(
            steem.commit.update_memo_key(args.key, account=args.account))

    elif args.command == "newaccount":
        import getpass
        while True:
            pw = getpass.getpass("New Account Passphrase: ")
            if not pw:
                print("You cannot chosen an empty password!")
                continue
            else:
                pwck = getpass.getpass("Confirm New Account Passphrase: ")
                if pw == pwck:
                    break
                else:
                    print("Given Passphrases do not match!")
        print_json(
            steem.commit.create_account(
                args.accountname,
                creator=args.account,
                password=pw,
                delegation_fee_steem=args.fee,
            ))

    elif args.command == "importaccount":
        from steembase.account import PasswordKey
        import getpass
        password = getpass.getpass("Account Passphrase: ")
        account = Account(args.account)
        imported = False

        if "owner" in args.roles:
            owner_key = PasswordKey(args.account, password, role="owner")
            owner_pubkey = format(owner_key.get_public_key(), "STM")
            if owner_pubkey in [x[0] for x in account["owner"]["key_auths"]]:
                print("Importing owner key!")
                owner_privkey = owner_key.get_private_key()
                steem.commit.wallet.addPrivateKey(owner_privkey)
                imported = True

        if "active" in args.roles:
            active_key = PasswordKey(args.account, password, role="active")
            active_pubkey = format(active_key.get_public_key(), "STM")
            if active_pubkey in [x[0] for x in account["active"]["key_auths"]]:
                print("Importing active key!")
                active_privkey = active_key.get_private_key()
                steem.commit.wallet.addPrivateKey(active_privkey)
                imported = True

        if "posting" in args.roles:
            posting_key = PasswordKey(args.account, password, role="posting")
            posting_pubkey = format(posting_key.get_public_key(), "STM")
            if posting_pubkey in [
                x[0] for x in account["posting"]["key_auths"]
            ]:
                print("Importing posting key!")
                posting_privkey = posting_key.get_private_key()
                steem.commit.wallet.addPrivateKey(posting_privkey)
                imported = True

        if "memo" in args.roles:
            memo_key = PasswordKey(args.account, password, role="memo")
            memo_pubkey = format(memo_key.get_public_key(), "STM")
            if memo_pubkey == account["memo_key"]:
                print("Importing memo key!")
                memo_privkey = memo_key.get_private_key()
                steem.commit.wallet.addPrivateKey(memo_privkey)
                imported = True

        if not imported:
            print("No matching key(s) found. Password correct?")

    elif args.command == "sign":
        if args.file and args.file != "-":
            if not os.path.isfile(args.file):
                raise Exception("File %s does not exist!" % args.file)
            with open(args.file) as fp:
                tx = fp.read()
        else:
            tx = sys.stdin.read()
        tx = eval(tx)
        print_json(steem.commit.sign(tx))

    elif args.command == "broadcast":
        if args.file and args.file != "-":
            if not os.path.isfile(args.file):
                raise Exception("File %s does not exist!" % args.file)
            with open(args.file) as fp:
                tx = fp.read()
        else:
            tx = sys.stdin.read()
        tx = eval(tx)
        steem.commit.broadcast(tx)

    elif args.command == "buy":
        if args.asset == "SBD":
            price = 1.0 / args.price
        else:
            price = args.price
        dex = Dex(steem)
        print_json(
            dex.buy(args.amount, args.asset, price, account=args.account))

    elif args.command == "sell":
        if args.asset == "SBD":
            price = 1.0 / args.price
        else:
            price = args.price
        dex = Dex(steem)
        print_json(
            dex.sell(args.amount, args.asset, price, account=args.account))

    elif args.command == "cancel":
        dex = Dex(steem)
        print_json(dex.cancel(args.orderid))

    elif args.command == "approvewitness":
        print_json(
            steem.commit.approve_witness(args.witness, account=args.account))

    elif args.command == "disapprovewitness":
        print_json(
            steem.commit.disapprove_witness(
                args.witness, account=args.account))

    elif args.command == "resteem":
        print_json(steem.commit.resteem(args.identifier, account=args.account))

    elif args.command == "follow":
        print_json(
            steem.commit.follow(
                args.follow, what=args.what, account=args.account))

    elif args.command == "unfollow":
        print_json(
            steem.commit.unfollow(
                args.unfollow, what=args.what, account=args.account))

    elif args.command == "setprofile":
        from .profile import Profile
        keys = []
        values = []
        if args.pair:
            for pair in args.pair:
                key, value = pair.split("=")
                keys.append(key)
                values.append(value)
        if args.variable and args.value:
            keys.append(args.variable)
            values.append(args.value)

        profile = Profile(keys, values)

        account = Account(args.account)
        account["json_metadata"] = Profile(account["json_metadata"]
                                           if account["json_metadata"] else {})
        account["json_metadata"].update(profile)

        print_json(
            steem.commit.update_account_profile(
                account["json_metadata"], account=args.account))

    elif args.command == "delprofile":
        from .profile import Profile
        account = Account(args.account)
        account["json_metadata"] = Profile(account["json_metadata"])

        for var in args.variable:
            account["json_metadata"].remove(var)

        print_json(
            steem.commit.update_account_profile(
                account["json_metadata"], account=args.account))

    elif args.command == "witnessupdate":

        witness = Witness(args.witness)
        props = witness["props"]
        if args.account_creation_fee:
            props["account_creation_fee"] = str(
                Amount("%f STEEM" % args.account_creation_fee))
        if args.maximum_block_size:
            props["maximum_block_size"] = args.maximum_block_size
        if args.sbd_interest_rate:
            props["sbd_interest_rate"] = int(args.sbd_interest_rate * 100)

        print_json(
            steem.commit.witness_update(
                args.signing_key or witness["signing_key"],
                args.url or witness["url"],
                props,
                account=args.witness))

    elif args.command == "witnesscreate":
        props = {
            "account_creation_fee":
                str(Amount("%f STEEM" % args.account_creation_fee)),
            "maximum_block_size":
                args.maximum_block_size,
            "sbd_interest_rate":
                int(args.sbd_interest_rate * 100)
        }
        print_json(
            steem.commit.witness_update(
                args.signing_key, args.url, props, account=args.witness))

    else:
        print("No valid command given")
Exemplo n.º 10
0
def main():
    global args

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description="Command line tool to interact with the Steem network")
    """
        Default settings for all tools
    """
    parser.add_argument(
        '--node',
        type=str,
        default=config["node"],
        help=
        'Websocket URL for public Steem API (default: "wss://this.piston.rocks/")'
    )
    parser.add_argument('--rpcuser',
                        type=str,
                        default=config["rpcuser"],
                        help='Websocket user if authentication is required')
    parser.add_argument(
        '--rpcpassword',
        type=str,
        default=config["rpcpassword"],
        help='Websocket password if authentication is required')
    parser.add_argument('--nobroadcast',
                        '-d',
                        action='store_true',
                        help='Do not broadcast anything')
    parser.add_argument('--nowallet',
                        '-p',
                        action='store_true',
                        help='Do not load the wallet')
    parser.add_argument('--unsigned',
                        '-x',
                        action='store_true',
                        help='Do not try to sign the transaction')
    parser.add_argument('--expires',
                        '-e',
                        default=30,
                        help='Expiration time in seconds (defaults to 30)')
    parser.add_argument('--verbose',
                        '-v',
                        type=int,
                        default=3,
                        help='Verbosity')
    parser.add_argument(
        '--version',
        action='version',
        version='%(prog)s {version}'.format(version=__VERSION__))

    subparsers = parser.add_subparsers(help='sub-command help')
    """
        Command "set"
    """
    setconfig = subparsers.add_parser('set', help='Set configuration')
    setconfig.add_argument('key',
                           type=str,
                           choices=availableConfigurationKeys,
                           help='Configuration key')
    setconfig.add_argument('value', type=str, help='Configuration value')
    setconfig.set_defaults(command="set")
    """
        Command "config"
    """
    configconfig = subparsers.add_parser('config',
                                         help='Show local configuration')
    configconfig.set_defaults(command="config")
    """
        Command "info"
    """
    parser_info = subparsers.add_parser(
        'info', help='Show infos about piston and Steem')
    parser_info.set_defaults(command="info")
    """
        Command "changewalletpassphrase"
    """
    changepasswordconfig = subparsers.add_parser('changewalletpassphrase',
                                                 help='Change wallet password')
    changepasswordconfig.set_defaults(command="changewalletpassphrase")
    """
        Command "addkey"
    """
    addkey = subparsers.add_parser('addkey',
                                   help='Add a new key to the wallet')
    addkey.add_argument('wifkeys',
                        nargs='*',
                        type=str,
                        help='the private key in wallet import format (wif)')
    addkey.set_defaults(command="addkey")
    """
        Command "delkey"
    """
    delkey = subparsers.add_parser('delkey',
                                   help='Delete keys from the wallet')
    delkey.add_argument('pub',
                        nargs='*',
                        type=str,
                        help='the public key to delete from the wallet')
    delkey.set_defaults(command="delkey")
    """
        Command "getkey"
    """
    getkey = subparsers.add_parser(
        'getkey', help='Dump the privatekey of a pubkey from the wallet')
    getkey.add_argument(
        'pub',
        type=str,
        help='the public key for which to show the private key')
    getkey.set_defaults(command="getkey")
    """
        Command "listkeys"
    """
    listkeys = subparsers.add_parser('listkeys',
                                     help='List available keys in your wallet')
    listkeys.set_defaults(command="listkeys")
    """
        Command "listaccounts"
    """
    listaccounts = subparsers.add_parser(
        'listaccounts', help='List available accounts in your wallet')
    listaccounts.set_defaults(command="listaccounts")
    """
        Command "list"
    """
    parser_list = subparsers.add_parser('list', help='List posts on Steem')
    parser_list.set_defaults(command="list")
    parser_list.add_argument(
        '--start',
        type=str,
        help='Start list from this identifier (pagination)')
    parser_list.add_argument('--category',
                             type=str,
                             help='Only posts with in this category')
    parser_list.add_argument('--sort',
                             type=str,
                             default=config["list_sorting"],
                             choices=[
                                 "trending", "created", "active", "cashout",
                                 "payout", "votes", "children", "hot"
                             ],
                             help='Sort posts')
    parser_list.add_argument('--limit',
                             type=int,
                             default=config["limit"],
                             help='Limit posts by number')
    parser_list.add_argument('--columns',
                             type=str,
                             nargs="+",
                             help='Display custom columns')
    """
        Command "categories"
    """
    parser_categories = subparsers.add_parser('categories',
                                              help='Show categories')
    parser_categories.set_defaults(command="categories")
    parser_categories.add_argument(
        '--sort',
        type=str,
        default=config["categories_sorting"],
        choices=["trending", "best", "active", "recent"],
        help='Sort categories')
    parser_categories.add_argument('category',
                                   nargs="?",
                                   type=str,
                                   help='Only categories used by this author')
    parser_categories.add_argument('--limit',
                                   type=int,
                                   default=config["limit"],
                                   help='Limit categories by number')
    """
        Command "read"
    """
    parser_read = subparsers.add_parser('read', help='Read a post on Steem')
    parser_read.set_defaults(command="read")
    parser_read.add_argument(
        'post',
        type=str,
        help=
        '@author/permlink-identifier of the post to read (e.g. @xeroc/python-steem-0-1)'
    )
    parser_read.add_argument(
        '--full',
        action='store_true',
        help='Show full header information (YAML formated)')
    parser_read.add_argument('--comments',
                             action='store_true',
                             help='Also show all comments')
    parser_read.add_argument('--parents',
                             type=int,
                             default=0,
                             help='Show x parents for the reply')
    parser_read.add_argument(
        '--format',
        type=str,
        default=config["format"],
        help='Format post',
        choices=["markdown", "raw"],
    )
    """
        Command "post"
    """
    parser_post = subparsers.add_parser('post', help='Post something new')
    parser_post.set_defaults(command="post")
    parser_post.add_argument(
        '--author',
        type=str,
        required=False,
        default=config["default_author"],
        help=
        'Publish post as this user (requires to have the key installed in the wallet)'
    )
    parser_post.add_argument(
        '--permlink',
        type=str,
        required=False,
        help=
        'The permlink (together with the author identifies the post uniquely)')
    parser_post.add_argument('--category',
                             default=config["post_category"],
                             type=str,
                             help='Specify category')
    parser_post.add_argument(
        '--tags',
        default=[],
        help='Specify tags',
        nargs='*',
    )
    parser_post.add_argument('--title',
                             type=str,
                             required=False,
                             help='Title of the post')
    parser_post.add_argument(
        '--file',
        type=str,
        default=None,
        help='Filename to open. If not present, or "-", stdin will be used')
    """
        Command "reply"
    """
    reply = subparsers.add_parser('reply', help='Reply to an existing post')
    reply.set_defaults(command="reply")
    reply.add_argument(
        'replyto',
        type=str,
        help=
        '@author/permlink-identifier of the post to reply to (e.g. @xeroc/python-steem-0-1)'
    )
    reply.add_argument(
        '--author',
        type=str,
        required=False,
        default=config["default_author"],
        help=
        'Publish post as this user (requires to have the key installed in the wallet)'
    )
    reply.add_argument(
        '--permlink',
        type=str,
        required=False,
        help=
        'The permlink (together with the author identifies the post uniquely)')
    reply.add_argument('--title',
                       type=str,
                       required=False,
                       help='Title of the post')
    reply.add_argument('--file',
                       type=str,
                       required=False,
                       help='Send file as responds. If "-", read from stdin')
    """
        Command "edit"
    """
    parser_edit = subparsers.add_parser('edit',
                                        help='Edit to an existing post')
    parser_edit.set_defaults(command="edit")
    parser_edit.add_argument(
        'post',
        type=str,
        help=
        '@author/permlink-identifier of the post to edit to (e.g. @xeroc/python-steem-0-1)'
    )
    parser_edit.add_argument('--author',
                             type=str,
                             required=False,
                             default=config["default_author"],
                             help='Post an edit as another author')
    parser_edit.add_argument('--file',
                             type=str,
                             required=False,
                             help='Patch with content of this file')
    parser_edit.add_argument(
        '--replace',
        action='store_true',
        help="Don't patch but replace original post (will make you lose votes)"
    )
    """
        Command "upvote"
    """
    parser_upvote = subparsers.add_parser('upvote', help='Upvote a post')
    parser_upvote.set_defaults(command="upvote")
    parser_upvote.add_argument(
        'post',
        type=str,
        help=
        '@author/permlink-identifier of the post to upvote to (e.g. @xeroc/python-steem-0-1)'
    )
    parser_upvote.add_argument('--voter',
                               type=str,
                               required=False,
                               default=config["default_voter"],
                               help='The voter account name')
    parser_upvote.add_argument('--weight',
                               type=float,
                               default=config["default_vote_weight"],
                               required=False,
                               help='Actual weight (from 0.1 to 100.0)')
    """
        Command "downvote"
    """
    parser_downvote = subparsers.add_parser('downvote', help='Downvote a post')
    parser_downvote.set_defaults(command="downvote")
    parser_downvote.add_argument('--voter',
                                 type=str,
                                 default=config["default_voter"],
                                 help='The voter account name')
    parser_downvote.add_argument(
        'post',
        type=str,
        help=
        '@author/permlink-identifier of the post to downvote to (e.g. @xeroc/python-steem-0-1)'
    )
    parser_downvote.add_argument('--weight',
                                 type=float,
                                 default=config["default_vote_weight"],
                                 required=False,
                                 help='Actual weight (from 0.1 to 100.0)')
    """
        Command "replies"
    """
    replies = subparsers.add_parser('replies',
                                    help='Show recent replies to your posts')
    replies.set_defaults(command="replies")
    replies.add_argument('--author',
                         type=str,
                         required=False,
                         default=config["default_author"],
                         help='Show replies to this author')
    replies.add_argument('--limit',
                         type=int,
                         default=config["limit"],
                         help='Limit posts by number')
    """
        Command "transfer"
    """
    parser_transfer = subparsers.add_parser('transfer', help='Transfer STEEM')
    parser_transfer.set_defaults(command="transfer")
    parser_transfer.add_argument('to', type=str, help='Recepient')
    parser_transfer.add_argument('amount',
                                 type=float,
                                 help='Amount to transfer')
    parser_transfer.add_argument('asset',
                                 type=str,
                                 choices=["GOLOS", "GBG"],
                                 help='Asset to (i.e. STEEM or SDB)')
    parser_transfer.add_argument('memo',
                                 type=str,
                                 nargs="?",
                                 default="",
                                 help='Optional memo')
    parser_transfer.add_argument('--account',
                                 type=str,
                                 required=False,
                                 default=config["default_author"],
                                 help='Transfer from this account')
    """
        Command "powerup"
    """
    parser_powerup = subparsers.add_parser(
        'powerup', help='Power up (vest STEEM as STEEM POWER)')
    parser_powerup.set_defaults(command="powerup")
    parser_powerup.add_argument('amount',
                                type=str,
                                help='Amount of VESTS to powerup')
    parser_powerup.add_argument('--account',
                                type=str,
                                required=False,
                                default=config["default_author"],
                                help='Powerup from this account')
    parser_powerup.add_argument('--to',
                                type=str,
                                required=False,
                                default=config["default_author"],
                                help='Powerup this account')
    """
        Command "powerdown"
    """
    parser_powerdown = subparsers.add_parser(
        'powerdown',
        help='Power down (start withdrawing STEEM from STEEM POWER)')
    parser_powerdown.set_defaults(command="powerdown")
    parser_powerdown.add_argument('amount',
                                  type=str,
                                  help='Amount of VESTS to powerdown')
    parser_powerdown.add_argument('--account',
                                  type=str,
                                  required=False,
                                  default=config["default_author"],
                                  help='powerdown from this account')
    """
        Command "powerdownroute"
    """
    parser_powerdownroute = subparsers.add_parser(
        'powerdownroute', help='Setup a powerdown route')
    parser_powerdownroute.set_defaults(command="powerdownroute")
    parser_powerdownroute.add_argument(
        'to',
        type=str,
        default=config["default_author"],
        help='The account receiving either VESTS/SteemPower or STEEM.')
    parser_powerdownroute.add_argument(
        '--percentage',
        type=float,
        default=100,
        help='The percent of the withdraw to go to the "to" account')
    parser_powerdownroute.add_argument(
        '--account',
        type=str,
        default=config["default_author"],
        help='The account which is powering down')
    parser_powerdownroute.add_argument(
        '--auto_vest',
        action='store_true',
        help=('Set to true if the from account should receive the VESTS as'
              'VESTS, or false if it should receive them as STEEM.'))
    """
        Command "convert"
    """
    parser_convert = subparsers.add_parser(
        'convert',
        help='Convert STEEMDollars to Steem (takes a week to settle)')
    parser_convert.set_defaults(command="convert")
    parser_convert.add_argument('amount',
                                type=float,
                                help='Amount of SBD to convert')
    parser_convert.add_argument('--account',
                                type=str,
                                required=False,
                                default=config["default_author"],
                                help='Convert from this account')
    """
        Command "balance"
    """
    parser_balance = subparsers.add_parser(
        'balance', help='Show the balance of one more more accounts')
    parser_balance.set_defaults(command="balance")
    parser_balance.add_argument(
        'account',
        type=str,
        nargs="*",
        default=config["default_author"],
        help='balance of these account (multiple accounts allowed)')
    """
        Command "history"
    """
    parser_history = subparsers.add_parser(
        'history', help='Show the history of an account')
    parser_history.set_defaults(command="history")
    parser_history.add_argument('account',
                                type=str,
                                nargs="?",
                                default=config["default_author"],
                                help='History of this account')
    parser_history.add_argument('--limit',
                                type=int,
                                default=config["limit"],
                                help='Limit number of entries')
    parser_history.add_argument('--memos',
                                action='store_true',
                                help='Show (decode) memos')
    parser_history.add_argument(
        '--first',
        type=int,
        default=99999999999999,
        help='Transactioon numer (#) of the last transaction to show.')
    parser_history.add_argument('--types',
                                type=str,
                                nargs="*",
                                default=[],
                                help='Show only these operation types')
    """
        Command "interest"
    """
    interest = subparsers.add_parser(
        'interest', help='Get information about interest payment')
    interest.set_defaults(command="interest")
    interest.add_argument('account',
                          type=str,
                          nargs="*",
                          default=config["default_author"],
                          help='Inspect these accounts')
    """
        Command "permissions"
    """
    parser_permissions = subparsers.add_parser(
        'permissions', help='Show permissions of an account')
    parser_permissions.set_defaults(command="permissions")
    parser_permissions.add_argument('account',
                                    type=str,
                                    nargs="?",
                                    default=config["default_author"],
                                    help='Account to show permissions for')
    """
        Command "allow"
    """
    parser_allow = subparsers.add_parser(
        'allow', help='Allow an account/key to interact with your account')
    parser_allow.set_defaults(command="allow")
    parser_allow.add_argument('--account',
                              type=str,
                              nargs="?",
                              default=config["default_author"],
                              help='The account to allow action for')
    parser_allow.add_argument(
        'foreign_account',
        type=str,
        nargs="?",
        help=
        'The account or key that will be allowed to interact as your account')
    parser_allow.add_argument(
        '--permission',
        type=str,
        default="posting",
        choices=["owner", "posting", "active"],
        help=('The permission to grant (defaults to "posting")'))
    parser_allow.add_argument(
        '--weight',
        type=int,
        default=None,
        help=('The weight to use instead of the (full) threshold. '
              'If the weight is smaller than the threshold, '
              'additional signatures are required'))
    parser_allow.add_argument(
        '--threshold',
        type=int,
        default=None,
        help=('The permission\'s threshold that needs to be reached '
              'by signatures to be able to interact'))
    """
        Command "disallow"
    """
    parser_disallow = subparsers.add_parser(
        'disallow',
        help='Remove allowance an account/key to interact with your account')
    parser_disallow.set_defaults(command="disallow")
    parser_disallow.add_argument('--account',
                                 type=str,
                                 nargs="?",
                                 default=config["default_author"],
                                 help='The account to disallow action for')
    parser_disallow.add_argument(
        'foreign_account',
        type=str,
        help=
        'The account or key whose allowance to interact as your account will be removed'
    )
    parser_disallow.add_argument(
        '--permission',
        type=str,
        default="posting",
        choices=["owner", "posting", "active"],
        help=('The permission to remove (defaults to "posting")'))
    parser_disallow.add_argument(
        '--threshold',
        type=int,
        default=None,
        help=('The permission\'s threshold that needs to be reached '
              'by signatures to be able to interact'))
    """
        Command "newaccount"
    """
    parser_newaccount = subparsers.add_parser('newaccount',
                                              help='Create a new account')
    parser_newaccount.set_defaults(command="newaccount")
    parser_newaccount.add_argument('accountname',
                                   type=str,
                                   help='New account name')
    parser_newaccount.add_argument('--account',
                                   type=str,
                                   required=False,
                                   default=config["default_author"],
                                   help='Account that pays the fee')
    """
        Command "importaccount"
    """
    parser_importaccount = subparsers.add_parser(
        'importaccount', help='Import an account using a passphrase')
    parser_importaccount.set_defaults(command="importaccount")
    parser_importaccount.add_argument('account', type=str, help='Account name')
    """
        Command "updateMemoKey"
    """
    parser_updateMemoKey = subparsers.add_parser(
        'updatememokey', help='Update an account\'s memo key')
    parser_updateMemoKey.set_defaults(command="updatememokey")
    parser_updateMemoKey.add_argument(
        '--account',
        type=str,
        nargs="?",
        default=config["default_author"],
        help='The account to updateMemoKey action for')
    parser_updateMemoKey.add_argument('--key',
                                      type=str,
                                      default=None,
                                      help='The new memo key')
    """
        Command "sign"
    """
    parser_sign = subparsers.add_parser(
        'sign',
        help='Sign a provided transaction with available and required keys')
    parser_sign.set_defaults(command="sign")
    parser_sign.add_argument(
        '--file',
        type=str,
        required=False,
        help=
        'Load transaction from file. If "-", read from stdin (defaults to "-")'
    )
    """
        Command "broadcast"
    """
    parser_broadcast = subparsers.add_parser(
        'broadcast', help='broadcast a signed transaction')
    parser_broadcast.set_defaults(command="broadcast")
    parser_broadcast.add_argument(
        '--file',
        type=str,
        required=False,
        help=
        'Load transaction from file. If "-", read from stdin (defaults to "-")'
    )
    """
        Command "web"
    """
    webconfig = subparsers.add_parser('web',
                                      help='Launch web version of piston')
    webconfig.set_defaults(command="web")
    webconfig.add_argument('--port',
                           type=int,
                           default=config["web:port"],
                           help='Port to open for internal web requests')
    webconfig.add_argument('--host',
                           type=str,
                           default=config["web:host"],
                           help='Host address to listen to')
    """
        Command "orderbook"
    """
    orderbook = subparsers.add_parser(
        'orderbook', help='Obtain orderbook of the internal market')
    orderbook.set_defaults(command="orderbook")
    orderbook.add_argument('--chart',
                           action='store_true',
                           help="Enable charting (requires matplotlib)")
    """
        Command "buy"
    """
    parser_buy = subparsers.add_parser(
        'buy', help='Buy GOLOS or GBG from the internal market')
    parser_buy.set_defaults(command="buy")
    parser_buy.add_argument('amount', type=float, help='Amount to buy')
    parser_buy.add_argument('asset',
                            type=str,
                            choices=["GOLOS", "GBG"],
                            help='Asset to buy (i.e. GOLOS or GBG)')
    parser_buy.add_argument('price',
                            type=float,
                            help='Limit buy price denoted in (GBG per GOLOS)')
    parser_buy.add_argument(
        '--account',
        type=str,
        required=False,
        default=config["default_account"],
        help='Buy with this account (defaults to "default_account")')
    """
        Command "sell"
    """
    parser_sell = subparsers.add_parser(
        'sell', help='Sell GOLOS or GBG from the internal market')
    parser_sell.set_defaults(command="sell")
    parser_sell.add_argument('amount', type=float, help='Amount to sell')
    parser_sell.add_argument('asset',
                             type=str,
                             choices=["GOLOS", "GBG"],
                             help='Asset to sell (i.e. GOLOS or GBG)')
    parser_sell.add_argument(
        'price',
        type=float,
        help='Limit sell price denoted in (GBG per GOLOS)')
    parser_sell.add_argument(
        '--account',
        type=str,
        required=False,
        default=config["default_account"],
        help='Sell from this account (defaults to "default_account")')
    """
        Parse Arguments
    """
    args = parser.parse_args()

    # Logging
    log = logging.getLogger(__name__)
    verbosity = ["critical", "error", "warn", "info",
                 "debug"][int(min(args.verbose, 4))]
    log.setLevel(getattr(logging, verbosity.upper()))
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    ch = logging.StreamHandler()
    ch.setLevel(getattr(logging, verbosity.upper()))
    ch.setFormatter(formatter)
    log.addHandler(ch)

    # GrapheneAPI logging
    if args.verbose > 4:
        verbosity = ["critical", "error", "warn", "info",
                     "debug"][int(min((args.verbose - 4), 4))]
        gphlog = logging.getLogger("graphenebase")
        gphlog.setLevel(getattr(logging, verbosity.upper()))
        gphlog.addHandler(ch)
    if args.verbose > 8:
        verbosity = ["critical", "error", "warn", "info",
                     "debug"][int(min((args.verbose - 8), 4))]
        gphlog = logging.getLogger("grapheneapi")
        gphlog.setLevel(getattr(logging, verbosity.upper()))
        gphlog.addHandler(ch)

    if not hasattr(args, "command"):
        parser.print_help()
        sys.exit(2)

    # We don't require RPC for these commands
    rpc_not_required = ["set", "config", "web", ""]
    if args.command not in rpc_not_required and args.command:
        options = {
            "node": args.node,
            "rpcuser": args.rpcuser,
            "rpcpassword": args.rpcpassword,
            "nobroadcast": args.nobroadcast,
            "unsigned": args.unsigned,
            "expires": args.expires
        }

        # preload wallet with empty keys
        if args.nowallet:
            options.update({"wif": []})

        # Signing only requires the wallet, no connection
        # essential for offline/coldstorage signing
        if args.command == "sign":
            options.update({"offline": True})

        steem = SteemConnector(**options).getSteem()

    if args.command == "set":
        if (args.key in ["default_author", "default_voter", "default_account"]
                and args.value[0] == "@"):
            args.value = args.value[1:]
        config[args.key] = args.value

    elif args.command == "config":
        t = PrettyTable(["Key", "Value"])
        t.align = "l"
        for key in config:
            if key in availableConfigurationKeys:  # hide internal config data
                t.add_row([key, config[key]])
        print(t)

    elif args.command == "info":
        t = PrettyTable(["Key", "Value"])
        t.align = "l"
        info = steem.rpc.get_dynamic_global_properties()
        median_price = steem.rpc.get_current_median_history_price()
        steem_per_mvest = (
            float(info["total_vesting_fund_steem"].split(" ")[0]) /
            (float(info["total_vesting_shares"].split(" ")[0]) / 1e6))
        price = (float(median_price["base"].split(" ")[0]) /
                 float(median_price["quote"].split(" ")[0]))
        for key in info:
            t.add_row([key, info[key]])
        t.add_row(["steem per mvest", steem_per_mvest])
        t.add_row(["internal price", price])
        print(t)

    elif args.command == "changewalletpassphrase":
        steem.wallet.changePassphrase()

    elif args.command == "addkey":
        pub = None
        if len(args.wifkeys):
            for wifkey in args.wifkeys:
                pub = (steem.wallet.addPrivateKey(wifkey))
                if pub:
                    print(pub)
        else:
            import getpass
            wifkey = ""
            while True:
                wifkey = getpass.getpass('Private Key (wif) [Enter to quit]:')
                if not wifkey:
                    break
                pub = (steem.wallet.addPrivateKey(wifkey))
                if pub:
                    print(pub)

        if pub:
            name = steem.wallet.getAccountFromPublicKey(pub)
            print("Setting new default user: %s" % name)
            print("You can change these settings with:")
            print("    piston set default_author x")
            print("    piston set default_voter x")
            config["default_author"] = name
            config["default_voter"] = name

    elif args.command == "delkey":
        if confirm("Are you sure you want to delete keys from your wallet?\n"
                   "This step is IRREVERSIBLE! If you don't have a backup, "
                   "You may lose access to your account!"):
            for pub in args.pub:
                steem.wallet.removePrivateKeyFromPublicKey(pub)

    elif args.command == "getkey":
        print(steem.wallet.getPrivateKeyForPublicKey(args.pub))

    elif args.command == "listkeys":
        t = PrettyTable(["Available Key"])
        t.align = "l"
        for key in steem.wallet.getPublicKeys():
            t.add_row([key])
        print(t)

    elif args.command == "listaccounts":
        t = PrettyTable(["Name", "Type", "Available Key"])
        t.align = "l"
        for account in steem.wallet.getAccounts():
            t.add_row([
                account["name"] or "n/a", account["type"] or "n/a",
                account["pubkey"]
            ])
        print(t)

    elif args.command == "reply":
        from textwrap import indent
        parent = steem.get_content(args.replyto)
        if parent["id"] == "0.0.0":
            print("Can't find post %s" % args.replyto)
            return

        reply_message = indent(parent["body"], "> ")

        post = frontmatter.Post(
            reply_message, **{
                "title":
                args.title if args.title else "Re: " + parent["title"],
                "author": args.author if args.author else "required",
                "replyto": args.replyto,
            })

        meta, json_meta, message = yaml_parse_file(args, initial_content=post)

        for required in ["author", "title"]:
            if (required not in meta or not meta[required]
                    or meta[required] == "required"):
                print("'%s' required!" % required)
                # TODO, instead of terminating here, send the user back
                # to the EDITOR
                return

        pprint(
            steem.reply(
                meta["replyto"],
                message,
                title=meta["title"],
                author=meta["author"],
                meta=json_meta,
            ))

    elif args.command == "post" or args.command == "yaml":
        initmeta = {
            "title": args.title if args.title else "required",
            "author": args.author if args.author else "required",
            "category": args.category if args.category else "required",
        }
        if args.tags:
            initmeta["tags"] = args.tags
        post = frontmatter.Post("", **initmeta)

        meta, json_meta, body = yaml_parse_file(args, initial_content=post)

        if not body:
            print("Empty body! Not posting!")
            return

        for required in ["author", "title", "category"]:
            if (required not in meta or not meta[required]
                    or meta[required] == "required"):
                print("'%s' required!" % required)
                # TODO, instead of terminating here, send the user back
                # to the EDITOR
                return

        pprint(
            steem.post(
                meta["title"],
                body,
                author=meta["author"],
                category=meta["category"],
                meta=json_meta,
            ))

    elif args.command == "edit":
        original_post = steem.get_content(args.post)

        edited_message = None
        if original_post["id"] == "0.0.0":
            print("Can't find post %s" % args.post)
            return

        post = frontmatter.Post(
            original_post["body"], **{
                "title": original_post["title"] + " (immutable)",
                "author": original_post["author"] + " (immutable)",
                "tags": original_post["_tags"]
            })

        meta, json_meta, edited_message = yaml_parse_file(args,
                                                          initial_content=post)
        pprint(
            steem.edit(
                args.post,
                edited_message,
                replace=args.replace,
                meta=json_meta,
            ))

    elif args.command == "upvote" or args.command == "downvote":
        post = Post(steem, args.post)
        if args.command == "downvote":
            weight = -float(args.weight)
        else:
            weight = +float(args.weight)
        if not args.voter:
            print("Not voter provided!")
            return
        pprint(post.vote(weight, voter=args.voter))

    elif args.command == "read":
        post_author, post_permlink = resolveIdentifier(args.post)

        if args.parents:
            # FIXME inconsistency, use @author/permlink instead!
            dump_recursive_parents(steem.rpc,
                                   post_author,
                                   post_permlink,
                                   args.parents,
                                   format=args.format)

        if not args.comments and not args.parents:
            post = steem.get_content(args.post)

            if post["id"] == "0.0.0":
                print("Can't find post %s" % args.post)
                return
            if args.format == "markdown":
                body = markdownify(post["body"])
            else:
                body = post["body"]

            if args.full:
                meta = {}
                for key in post:
                    if key in ["steem", "body"]:
                        continue
                    meta[key] = post[key]
                yaml = frontmatter.Post(body, **meta)
                print(frontmatter.dumps(yaml))
            else:
                print(body)

        if args.comments:
            dump_recursive_comments(steem.rpc,
                                    post_author,
                                    post_permlink,
                                    format=args.format)

    elif args.command == "categories":
        categories = steem.get_categories(sort=args.sort,
                                          begin=args.category,
                                          limit=args.limit)
        t = PrettyTable(["name", "discussions", "payouts"])
        t.align = "l"
        for category in categories:
            t.add_row([
                category["name"],
                category["discussions"],
                category["total_payouts"],
            ])
        print(t)

    elif args.command == "list":
        list_posts(
            steem.get_posts(limit=args.limit,
                            sort=args.sort,
                            category=args.category,
                            start=args.start), args.columns)

    elif args.command == "replies":
        if not args.author:
            print("Please specify an author via --author\n "
                  "or define your default author with:\n"
                  "   piston set default_author x")
        else:
            discussions = steem.get_replies(args.author)
            list_posts(discussions[0:args.limit])

    elif args.command == "transfer":
        pprint(
            steem.transfer(args.to,
                           args.amount,
                           args.asset,
                           memo=args.memo,
                           account=args.account))

    elif args.command == "powerup":
        pprint(
            steem.transfer_to_vesting(args.amount,
                                      account=args.account,
                                      to=args.to))

    elif args.command == "powerdown":
        pprint(steem.withdraw_vesting(
            args.amount,
            account=args.account,
        ))

    elif args.command == "convert":
        pprint(steem.convert(
            args.amount,
            account=args.account,
        ))

    elif args.command == "powerdownroute":
        pprint(
            steem.set_withdraw_vesting_route(args.to,
                                             percentage=args.percentage,
                                             account=args.account,
                                             auto_vest=args.auto_vest))

    elif args.command == "balance":
        t = PrettyTable(
            ["Account", "GOLOS", "GBG", "GESTS", "VESTS (in STEEM)"])
        t.align = "r"
        if isinstance(args.account, str):
            args.account = [args.account]
        for a in args.account:
            b = steem.get_balances(a)
            t.add_row([
                a, b["balance"], b["sbd_balance"], b["vesting_shares"],
                b["vesting_shares_steem"]
            ])
        print(t)

    elif args.command == "history":
        t = PrettyTable(["#", "time/block", "Operation", "Details"])
        t.align = "r"
        if isinstance(args.account, str):
            args.account = [args.account]
        if isinstance(args.types, str):
            args.types = [args.types]

        for a in args.account:
            for b in steem.rpc.account_history(a,
                                               args.first,
                                               limit=args.limit,
                                               only_ops=args.types):
                t.add_row([
                    b[0],
                    "%s (%s)" % (b[1]["timestamp"], b[1]["block"]),
                    b[1]["op"][0],
                    format_operation_details(b[1]["op"], memos=args.memos),
                ])
        print(t)

    elif args.command == "interest":
        t = PrettyTable([
            "Account", "Last Interest Payment", "Next Payment",
            "Interest rate", "Interest"
        ])
        t.align = "r"
        if isinstance(args.account, str):
            args.account = [args.account]
        for a in args.account:
            i = steem.interest(a)

            t.add_row([
                a,
                i["last_payment"],
                "in %s" % strfage(i["next_payment_duration"]),
                "%.1f%%" % i["interest_rate"],
                "%.3f GBG" % i["interest"],
            ])
        print(t)

    elif args.command == "permissions":
        account = steem.rpc.get_account(args.account)
        print_permissions(account)

    elif args.command == "allow":
        if not args.foreign_account:
            from steembase.account import PasswordKey
            pwd = get_terminal(text="Password for Key Derivation: ",
                               confirm=True)
            args.foreign_account = format(
                PasswordKey(args.account, pwd, args.permission).get_public(),
                "GLS")
        pprint(
            steem.allow(args.foreign_account,
                        weight=args.weight,
                        account=args.account,
                        permission=args.permission,
                        threshold=args.threshold))

    elif args.command == "disallow":
        pprint(
            steem.disallow(args.foreign_account,
                           account=args.account,
                           permission=args.permission,
                           threshold=args.threshold))

    elif args.command == "updatememokey":
        if not args.key:
            # Loop until both match
            from steembase.account import PasswordKey
            pw = get_terminal(text="Password for Memo Key: ",
                              confirm=True,
                              allowedempty=False)
            memo_key = PasswordKey(args.account, pw, "memo")
            args.key = format(memo_key.get_public_key(), "GLS")
            memo_privkey = memo_key.get_private_key()
            # Add the key to the wallet
            if not args.nobroadcast:
                steem.wallet.addPrivateKey(memo_privkey)
        pprint(steem.update_memo_key(args.key, account=args.account))

    elif args.command == "newaccount":
        import getpass
        while True:
            pw = getpass.getpass("New Account Passphrase: ")
            if not pw:
                print("You cannot chosen an empty password!")
                continue
            else:
                pwck = getpass.getpass("Confirm New Account Passphrase: ")
                if (pw == pwck):
                    break
                else:
                    print("Given Passphrases do not match!")
        pprint(
            steem.create_account(
                args.accountname,
                creator=args.account,
                password=pw,
            ))

    elif args.command == "importaccount":
        from steembase.account import PasswordKey
        import getpass
        password = getpass.getpass("Account Passphrase: ")

        posting_key = PasswordKey(args.account, password, role="posting")
        active_key = PasswordKey(args.account, password, role="active")
        memo_key = PasswordKey(args.account, password, role="memo")
        posting_pubkey = format(posting_key.get_public_key(), "GLS")
        active_pubkey = format(active_key.get_public_key(), "GLS")
        memo_pubkey = format(memo_key.get_public_key(), "GLS")

        account = steem.rpc.get_account(args.account)

        imported = False
        if active_pubkey in [x[0] for x in account["active"]["key_auths"]]:
            active_privkey = active_key.get_private_key()
            steem.wallet.addPrivateKey(active_privkey)
            imported = True

        if posting_pubkey in [x[0] for x in account["posting"]["key_auths"]]:
            posting_privkey = posting_key.get_private_key()
            steem.wallet.addPrivateKey(posting_privkey)
            imported = True

        if memo_pubkey == account["memo_key"]:
            memo_privkey = memo_key.get_private_key()
            steem.wallet.addPrivateKey(memo_privkey)
            imported = True

        if not imported:
            print("No keys matched! Invalid password?")

    elif args.command == "sign":
        if args.file and args.file != "-":
            if not os.path.isfile(args.file):
                raise Exception("File %s does not exist!" % args.file)
            with open(args.file) as fp:
                tx = fp.read()
        else:
            tx = sys.stdin.read()
        tx = eval(tx)
        pprint(steem.sign(tx))

    elif args.command == "broadcast":
        if args.file and args.file != "-":
            if not os.path.isfile(args.file):
                raise Exception("File %s does not exist!" % args.file)
            with open(args.file) as fp:
                tx = fp.read()
        else:
            tx = sys.stdin.read()
        tx = eval(tx)
        steem.broadcast(tx)

    elif args.command == "web":
        SteemConnector(node=args.node,
                       rpcuser=args.rpcuser,
                       rpcpassword=args.rpcpassword,
                       nobroadcast=args.nobroadcast,
                       num_retries=1)
        from . import web
        web.run(port=args.port, host=args.host)

    elif args.command == "orderbook":
        if args.chart:
            try:
                import numpy
                import Gnuplot
                from itertools import accumulate
            except:
                print(
                    "To use --chart, you need gnuplot and gnuplot-py installed"
                )
                sys.exit(1)
        orderbook = steem.dex().returnOrderBook()

        if args.chart:
            g = Gnuplot.Gnuplot()
            g.title("Steem internal market - GBG:GOLOS")
            g.xlabel("price")
            g.ylabel("volume")
            g("""
                set style data line
                set term xterm
                set border 15
            """)
            xbids = [x["price"] for x in orderbook["bids"]]
            ybids = list(accumulate([x["gbg"] for x in orderbook["bids"]]))
            dbids = Gnuplot.Data(xbids, ybids, with_="lines")
            xasks = [x["price"] for x in orderbook["asks"]]
            yasks = list(accumulate([x["gbg"] for x in orderbook["asks"]]))
            dasks = Gnuplot.Data(xasks, yasks, with_="lines")
            g("set terminal dumb")
            g.plot(dbids, dasks)  # write SVG data directly to stdout ...

        t = PrettyTable([
            "bid GBG", "sum bids GBG", "bid GOLOS", "sum bids GOLOS",
            "bid price", "+", "ask price", "ask GOLOS", "sum asks steem",
            "ask GBG", "sum asks GBG"
        ])
        t.align = "r"
        bidssteem = 0
        bidssbd = 0
        askssteem = 0
        askssbd = 0
        for i, o in enumerate(orderbook["asks"]):
            bidssbd += orderbook["bids"][i]["gbg"]
            bidssteem += orderbook["bids"][i]["golos"]
            askssbd += orderbook["asks"][i]["gbg"]
            askssteem += orderbook["asks"][i]["golos"]
            t.add_row([
                "%.3f Ṩ" % orderbook["bids"][i]["gbg"],
                "%.3f ∑" % bidssbd,
                "%.3f ȿ" % orderbook["bids"][i]["golos"],
                "%.3f ∑" % bidssteem,
                "%.3f Ṩ/ȿ" % orderbook["bids"][i]["price"], "|",
                "%.3f Ṩ/ȿ" % orderbook["asks"][i]["price"],
                "%.3f ȿ" % orderbook["asks"][i]["golos"],
                "%.3f ∑" % askssteem,
                "%.3f Ṩ" % orderbook["asks"][i]["gbg"],
                "%.3f ∑" % askssbd
            ])
        print(t)

    elif args.command == "buy":
        if args.asset == "GBG":
            price = 1.0 / args.price
        else:
            price = args.price
        pprint(steem.buy(args.amount, args.asset, price, account=args.account))

    elif args.command == "sell":
        if args.asset == "GBG":
            price = 1.0 / args.price
        else:
            price = args.price
        pprint(steem.sell(args.amount, args.asset, price,
                          account=args.account))

    else:
        print("No valid command given")
Exemplo n.º 11
0
    def create_account(
        self,
        account_name,
        json_meta=None,
        password=None,
        owner_key=None,
        active_key=None,
        posting_key=None,
        memo_key=None,
        additional_owner_keys=[],
        additional_active_keys=[],
        additional_posting_keys=[],
        additional_owner_accounts=[],
        additional_active_accounts=[],
        additional_posting_accounts=[],
        store_keys=True,
        store_owner_key=False,
        delegation_fee_steem='0 STEEM',
        creator=None,
    ):
        """ Create new account in Steem

            The brainkey/password can be used to recover all generated keys
            (see `steembase.account` for more details.

            By default, this call will use ``default_account`` to
            register a new name ``account_name`` with all keys being
            derived from a new brain key that will be returned. The
            corresponding keys will automatically be installed in the
            wallet.

            .. note:: Account creations cost a fee that is defined by
               the network. If you create an account, you will
               need to pay for that fee!

               **You can partially pay that fee by delegating VESTS.**

               To pay the fee in full in STEEM, leave
               ``delegation_fee_steem`` set to ``0 STEEM`` (Default).

               To pay the fee partially in STEEM, partially with delegated
               VESTS, set ``delegation_fee_steem`` to a value greater than ``1
               STEEM``. `Required VESTS will be calculated automatically.`

               To pay the fee with maximum amount of delegation, set
               ``delegation_fee_steem`` to ``1 STEEM``. `Required VESTS will be
               calculated automatically.`

            .. warning:: Don't call this method unless you know what
                          you are doing! Be sure to understand what this
                          method does and where to find the private keys
                          for your account.

        .. note:: Please note that this imports private keys (if password is
        present) into the wallet by default. However, it **does not import
        the owner key** unless `store_owner_key` is set to True (default
        False). Do NOT expect to be able to recover it from the wallet if
        you lose your password!

            :param str account_name: (**required**) new account name
            :param str json_meta: Optional meta data for the account
            :param str owner_key: Main owner key
            :param str active_key: Main active key
            :param str posting_key: Main posting key
            :param str memo_key: Main memo_key
            :param str password: Alternatively to providing keys, one
                                 can provide a password from which the
                                 keys will be derived
            :param list additional_owner_keys:  Additional owner public keys

            :param list additional_active_keys: Additional active public keys

            :param list additional_posting_keys: Additional posting public keys

            :param list additional_owner_accounts: Additional owner account
            names

            :param list additional_active_accounts: Additional active account
            names

            :param list additional_posting_accounts: Additional posting account
            names

            :param bool store_keys: Store new keys in the wallet (default:
            ``True``)

            :param bool store_owner_key: Store owner key in the wallet
            (default: ``False``)

            :param str delegation_fee_steem: (Optional) If set, `creator` pay a
            fee of this amount, and delegate the rest with VESTS (calculated
            automatically). Minimum: 1 STEEM. If left to 0 (Default), full fee
            is paid without VESTS delegation.

            :param str creator: which account should pay the registration fee
                                (defaults to ``default_account``)

        :raises AccountExistsException: if the account already exists on the
        blockchain

        """
        assert len(
            account_name) <= 16, "Account name must be at most 16 chars long"

        if not creator:
            creator = configStorage.get("default_account")
        if not creator:
            raise ValueError(
                "Not creator account given. Define it with " +
                "creator=x, or set the default_account using steempy")
        if password and (owner_key or posting_key or active_key or memo_key):
            raise ValueError("You cannot use 'password' AND provide keys!")

        # check if account already exists
        try:
            Account(account_name, steemd_instance=self.steemd)
        except:  # noqa FIXME(sneak)
            pass
        else:
            raise AccountExistsException

        " Generate new keys from password"
        from steembase.account import PasswordKey, PublicKey
        if password:
            posting_key = PasswordKey(account_name, password, role="posting")
            active_key = PasswordKey(account_name, password, role="active")
            owner_key = PasswordKey(account_name, password, role="owner")
            memo_key = PasswordKey(account_name, password, role="memo")
            posting_pubkey = posting_key.get_public_key()
            active_pubkey = active_key.get_public_key()
            owner_pubkey = owner_key.get_public_key()
            memo_pubkey = memo_key.get_public_key()
            posting_privkey = posting_key.get_private_key()
            active_privkey = active_key.get_private_key()
            owner_privkey = owner_key.get_private_key()
            memo_privkey = memo_key.get_private_key()
            # store private keys
            if store_keys:
                if store_owner_key:
                    self.wallet.addPrivateKey(owner_privkey)
                self.wallet.addPrivateKey(active_privkey)
                self.wallet.addPrivateKey(posting_privkey)
                self.wallet.addPrivateKey(memo_privkey)
        elif owner_key and posting_key and active_key and memo_key:
            posting_pubkey = PublicKey(
                posting_key, prefix=self.steemd.chain_params["prefix"])
            active_pubkey = PublicKey(
                active_key, prefix=self.steemd.chain_params["prefix"])
            owner_pubkey = PublicKey(owner_key,
                                     prefix=self.steemd.chain_params["prefix"])
            memo_pubkey = PublicKey(memo_key,
                                    prefix=self.steemd.chain_params["prefix"])
        else:
            raise ValueError(
                "Call incomplete! Provide either a password or public keys!")

        owner = format(owner_pubkey, self.steemd.chain_params["prefix"])
        active = format(active_pubkey, self.steemd.chain_params["prefix"])
        posting = format(posting_pubkey, self.steemd.chain_params["prefix"])
        memo = format(memo_pubkey, self.steemd.chain_params["prefix"])

        owner_key_authority = [[owner, 1]]
        active_key_authority = [[active, 1]]
        posting_key_authority = [[posting, 1]]
        owner_accounts_authority = []
        active_accounts_authority = []
        posting_accounts_authority = []

        # additional authorities
        for k in additional_owner_keys:
            owner_key_authority.append([k, 1])
        for k in additional_active_keys:
            active_key_authority.append([k, 1])
        for k in additional_posting_keys:
            posting_key_authority.append([k, 1])

        for k in additional_owner_accounts:
            owner_accounts_authority.append([k, 1])
        for k in additional_active_accounts:
            active_accounts_authority.append([k, 1])
        for k in additional_posting_accounts:
            posting_accounts_authority.append([k, 1])

        props = self.steemd.get_chain_properties()
        required_fee_steem = Amount(props["account_creation_fee"]).amount * 30

        required_fee_vests = 0
        delegation_fee_steem = Amount(delegation_fee_steem).amount
        if delegation_fee_steem:
            # creating accounts without delegation requires 30x
            # account_creation_fee creating account with delegation allows one
            # to use VESTS to pay the fee where the ratio must satisfy 1 STEEM
            # in fee == 5 STEEM in delegated VESTS

            delegated_sp_fee_mult = 5

            if delegation_fee_steem < 1:
                raise ValueError(
                    "When creating account with delegation, at least " +
                    "1 STEEM in fee must be paid.")

            # calculate required remaining fee in vests
            remaining_fee = required_fee_steem - delegation_fee_steem
            if remaining_fee > 0:
                required_sp = remaining_fee * delegated_sp_fee_mult
                required_fee_vests = Converter().sp_to_vests(required_sp) + 1

        s = {
            'creator': creator,
            'fee': '%s STEEM' % (delegation_fee_steem or required_fee_steem),
            'delegation': '%s VESTS' % required_fee_vests,
            'json_metadata': json_meta or {},
            'memo_key': memo,
            'new_account_name': account_name,
            'owner': {
                'account_auths': owner_accounts_authority,
                'key_auths': owner_key_authority,
                'weight_threshold': 1
            },
            'active': {
                'account_auths': active_accounts_authority,
                'key_auths': active_key_authority,
                'weight_threshold': 1
            },
            'posting': {
                'account_auths': posting_accounts_authority,
                'key_auths': posting_key_authority,
                'weight_threshold': 1
            },
            'prefix': self.steemd.chain_params["prefix"]
        }

        op = operations.AccountCreateWithDelegation(**s)

        return self.finalizeOp(op, creator, "active")
Exemplo n.º 12
0
    def create_account(self,
                       account_name,
                       json_meta={},
                       creator=None,
                       owner_key=None,
                       active_key=None,
                       posting_key=None,
                       memo_key=None,
                       password=None,
                       additional_owner_keys=[],
                       additional_active_keys=[],
                       additional_posting_keys=[],
                       additional_owner_accounts=[],
                       additional_active_accounts=[],
                       additional_posting_accounts=[],
                       storekeys=True,
                       ):
        """ Create new account in Steem

            The brainkey/password can be used to recover all generated keys (see
            `steembase.account` for more details.

            By default, this call will use ``default_author`` to
            register a new name ``account_name`` with all keys being
            derived from a new brain key that will be returned. The
            corresponding keys will automatically be installed in the
            wallet.

            .. note:: Account creations cost a fee that is defined by
                       the network. If you create an account, you will
                       need to pay for that fee!

            .. warning:: Don't call this method unless you know what
                          you are doing! Be sure to understand what this
                          method does and where to find the private keys
                          for your account.

            .. note:: Please note that this imports private keys
                      (if password is present) into the wallet by
                      default. However, it **does not import the owner
                      key** for security reasons. Do NOT expect to be
                      able to recover it from piston if you lose your
                      password!

            :param str account_name: (**required**) new account name
            :param str json_meta: Optional meta data for the account
            :param str creator: which account should pay the registration fee
                                (defaults to ``default_author``)
            :param str owner_key: Main owner key
            :param str active_key: Main active key
            :param str posting_key: Main posting key
            :param str memo_key: Main memo_key
            :param str password: Alternatively to providing keys, one
                                 can provide a password from which the
                                 keys will be derived
            :param array additional_owner_keys:  Additional owner public keys
            :param array additional_active_keys: Additional active public keys
            :param array additional_posting_keys: Additional posting public keys
            :param array additional_owner_accounts: Additional owner account names
            :param array additional_active_accounts: Additional acctive account names
            :param array additional_posting_accounts: Additional posting account names
            :param bool storekeys: Store new keys in the wallet (default: ``True``)
            :raises AccountExistsException: if the account already exists on the blockchain

        """
        if not creator and config["default_author"]:
            creator = config["default_author"]
        if not creator:
            raise ValueError(
                "Not creator account given. Define it with " +
                "creator=x, or set the default_author in piston")
        if password and (owner_key or posting_key or active_key or memo_key):
            raise ValueError(
                "You cannot use 'password' AND provide keys!"
            )

        account = None
        try:
            account = self.rpc.get_account(account_name)
        except:
            pass
        if account:
            raise AccountExistsException

        " Generate new keys from password"
        from steembase.account import PasswordKey, PublicKey
        if password:
            posting_key = PasswordKey(account_name, password, role="posting")
            active_key  = PasswordKey(account_name, password, role="active")
            owner_key   = PasswordKey(account_name, password, role="owner")
            memo_key    = PasswordKey(account_name, password, role="memo")
            posting_pubkey = posting_key.get_public_key()
            active_pubkey  = active_key.get_public_key()
            owner_pubkey   = owner_key.get_public_key()
            memo_pubkey    = memo_key.get_public_key()
            posting_privkey = posting_key.get_private_key()
            active_privkey  = active_key.get_private_key()
            # owner_privkey   = owner_key.get_private_key()
            memo_privkey    = memo_key.get_private_key()
            # store private keys
            if storekeys:
                # self.wallet.addPrivateKey(owner_privkey)
                self.wallet.addPrivateKey(active_privkey)
                self.wallet.addPrivateKey(posting_privkey)
                self.wallet.addPrivateKey(memo_privkey)
        elif (owner_key and posting_key and active_key and memo_key):
            posting_pubkey = PublicKey(posting_key, prefix=prefix)
            active_pubkey  = PublicKey(active_key, prefix=prefix)
            owner_pubkey   = PublicKey(owner_key, prefix=prefix)
            memo_pubkey    = PublicKey(memo_key, prefix=prefix)
        else:
            raise ValueError(
                "Call incomplete! Provide either a password or public keys!"
            )

        owner   = format(posting_pubkey, prefix)
        active  = format(active_pubkey, prefix)
        posting = format(owner_pubkey, prefix)
        memo    = format(memo_pubkey, prefix)

        owner_key_authority = [[owner, 1]]
        active_key_authority = [[active, 1]]
        posting_key_authority = [[posting, 1]]
        owner_accounts_authority = []
        active_accounts_authority = []
        posting_accounts_authority = []

        # additional authorities
        for k in additional_owner_keys:
            owner_key_authority.append([k, 1])
        for k in additional_active_keys:
            active_key_authority.append([k, 1])
        for k in additional_posting_keys:
            posting_key_authority.append([k, 1])

        for k in additional_owner_accounts:
            owner_accounts_authority.append([k, 1])
        for k in additional_active_accounts:
            active_accounts_authority.append([k, 1])
        for k in additional_posting_accounts:
            posting_accounts_authority.append([k, 1])

        props = self.rpc.get_chain_properties()
        fee = props["account_creation_fee"]
        s = {'creator': creator,
             'fee': fee,
             'json_metadata': json_meta,
             'memo_key': memo,
             'new_account_name': account_name,
             'owner': {'account_auths': owner_accounts_authority,
                       'key_auths': owner_key_authority,
                       'weight_threshold': 1},
             'active': {'account_auths': active_accounts_authority,
                        'key_auths': active_key_authority,
                        'weight_threshold': 1},
             'posting': {'account_auths': posting_accounts_authority,
                         'key_auths': posting_key_authority,
                         'weight_threshold': 1}}
        op = transactions.Account_create(**s)
        wif = self.wallet.getActiveKeyForAccount(creator)
        return self.executeOp(op, wif)
Exemplo n.º 13
0
def get_public_key_from_password(shared_dict, account_name, password):
    if account_name + password not in shared_dict:
        shared_dict[account_name + password] = str(
            PasswordKey(account_name, password,
                        'owner').get_private_key().pubkey)
    return shared_dict[account_name + password]