예제 #1
0
KeyPair generateKeysFromSeed (KeyType type, RippleAddress const& seed)
{
    KeyPair result;

    if (! seed.isSet())
    {
        return result;
    }

    if (type == KeyType::secp256k1)
    {
        RippleAddress generator = RippleAddress::createGeneratorPublic (seed);
        result.secretKey.setAccountPrivate (generator, seed, 0);
        result.publicKey.setAccountPublic (generator, 0);
    }
    else if (type == KeyType::ed25519)
    {
        uint256 secretkey = keyFromSeed (seed.getSeed());

        Blob ed25519_key (33);
        ed25519_key[0] = 0xED;

        assert (secretkey.size() + 1 == ed25519_key.size());
        memcpy (&ed25519_key[1], secretkey.data(), secretkey.size());
        result.secretKey.setAccountPrivate (ed25519_key);

        ed25519_publickey (secretkey.data(), &ed25519_key[1]);
        result.publicKey.setAccountPublic (ed25519_key);

        secretkey.zero();  // security erase
    }
    else
    {
        assert (false);  // not reached
    }

    return result;
}
예제 #2
0
TER AccountSetTransactor::doApply ()
{
    std::uint32_t const uTxFlags = mTxn.getFlags ();

    std::uint32_t const uFlagsIn = mTxnAccount->getFieldU32 (sfFlags);
    std::uint32_t uFlagsOut = uFlagsIn;

    std::uint32_t const uSetFlag = mTxn.getFieldU32 (sfSetFlag);
    std::uint32_t const uClearFlag  = mTxn.getFieldU32 (sfClearFlag);

    // legacy AccountSet flags
    bool bSetRequireDest   = (uTxFlags & TxFlag::requireDestTag) || (uSetFlag == asfRequireDest);
    bool bClearRequireDest = (uTxFlags & tfOptionalDestTag) || (uClearFlag == asfRequireDest);
    bool bSetRequireAuth   = (uTxFlags & tfRequireAuth) || (uSetFlag == asfRequireAuth);
    bool bClearRequireAuth = (uTxFlags & tfOptionalAuth) || (uClearFlag == asfRequireAuth);

    if (uTxFlags & tfAccountSetMask)
    {
        m_journal.trace << "Malformed transaction: Invalid flags set.";
        return temINVALID_FLAG;
    }

    //
    // RequireAuth (if this issuer needs to allow others to hold its IOUs)
    //

    if (bSetRequireAuth && bClearRequireAuth)
    {
        m_journal.trace << "Malformed transaction: Contradictory flags set.";
        return temINVALID_FLAG;
    }

    if (bSetRequireAuth && !is_bit_set (uFlagsIn, lsfRequireAuth))
    {
        if (!mEngine->view().dirIsEmpty (Ledger::getOwnerDirIndex (mTxnAccountID)))
        {
            m_journal.trace << "Retry: Owner directory not empty.";

            return is_bit_set(mParams, tapRETRY) ? terOWNERS : tecOWNERS;
        }

        m_journal.trace << "Set RequireAuth.";
        uFlagsOut   |= lsfRequireAuth;
    }

    if (bClearRequireAuth && is_bit_set (uFlagsIn, lsfRequireAuth))
    {
        m_journal.trace << "Clear RequireAuth.";
        uFlagsOut   &= ~lsfRequireAuth;
    }

    //
    // RequireDestTag
    //

    if (bSetRequireDest && bClearRequireDest)
    {
        m_journal.trace << "Malformed transaction: Contradictory flags set.";
        return temINVALID_FLAG;
    }

    if (bSetRequireDest && !is_bit_set (uFlagsIn, lsfRequireDestTag))
    {
        m_journal.trace << "Set lsfRequireDestTag.";
        uFlagsOut   |= lsfRequireDestTag;
    }

    if (bClearRequireDest && is_bit_set (uFlagsIn, lsfRequireDestTag))
    {
        m_journal.trace << "Clear lsfRequireDestTag.";
        uFlagsOut   &= ~lsfRequireDestTag;
    }

  
    //
    // InflationDest
    //

    if ( mTxn.isFieldPresent(sfInflationDest) )
    {
        RippleAddress aInflationDest = mTxn.getFieldAccount(sfInflationDest);

		if ( !aInflationDest.isSet() ){
			m_journal.debug << "AccountSet: Removing inflation destination.";

			mTxnAccount->makeFieldAbsent(sfInflationDest);
		}
		else
		{
			if (!mEngine->getLedger()->hasAccount(aInflationDest))
			{
				m_journal.debug << "AccountSet: Inflation destination account doesn't exist.";

				return temDST_NEEDED;
			}

			m_journal.debug << "AccountSet: Set inflation destination account.";

			mTxnAccount->setFieldAccount(sfInflationDest, aInflationDest);
		}

    }

    

    //
    // TransferRate
    //

    if (mTxn.isFieldPresent (sfTransferRate))
    {
        std::uint32_t      uRate   = mTxn.getFieldU32 (sfTransferRate);

        if (!uRate || uRate == QUALITY_ONE)
        {
            m_journal.trace << "unset transfer rate";
            mTxnAccount->makeFieldAbsent (sfTransferRate);
        }
        else if (uRate > QUALITY_ONE)
        {
            m_journal.trace << "set transfer rate";
            mTxnAccount->setFieldU32 (sfTransferRate, uRate);
        }
        else
        {
            m_journal.trace << "bad transfer rate";
            return temBAD_TRANSFER_RATE;
        }
    }

    if (uFlagsIn != uFlagsOut)
        mTxnAccount->setFieldU32 (sfFlags, uFlagsOut);

    return tesSUCCESS;
}
예제 #3
0
Json::Value walletPropose (Json::Value const& params)
{
    RippleAddress   naSeed;
    RippleAddress   naAccount;

    KeyType type = KeyType::secp256k1;

    bool const has_key_type   = params.isMember (jss::key_type);
    bool const has_passphrase = params.isMember (jss::passphrase);

    if (has_key_type)
    {
        // `key_type` must be valid if present.

        type = keyTypeFromString (params[jss::key_type].asString());

        if (type == KeyType::invalid)
        {
            return rpcError (rpcBAD_SEED);
        }

        naSeed = getSeedFromRPC (params);
    }
    else if (has_passphrase)
    {
        naSeed.setSeedGeneric (params[jss::passphrase].asString());
    }
    else
    {
        naSeed.setSeedRandom();
    }

    if (!naSeed.isSet())
    {
        return rpcError(rpcBAD_SEED);
    }

    if (type == KeyType::secp256k1)
    {
        RippleAddress naGenerator = RippleAddress::createGeneratorPublic (naSeed);
        naAccount.setAccountPublic (naGenerator, 0);
    }
    else if (type == KeyType::ed25519)
    {
        uint256 secretkey = keyFromSeed (naSeed.getSeed());

        Blob publickey (33);
        publickey[0] = 0xED;
        ed25519_publickey (secretkey.data(), &publickey[1]);
        secretkey.zero();  // security erase

        naAccount.setAccountPublic (publickey);
    }
    else
    {
        assert (false);  // not reached
    }

    Json::Value obj (Json::objectValue);

    obj[jss::master_seed] = naSeed.humanSeed ();
    obj[jss::master_seed_hex] = to_string (naSeed.getSeed ());
    obj[jss::master_key] = naSeed.humanSeed1751();
    obj[jss::account_id] = naAccount.humanAccountID ();
    obj[jss::public_key] = naAccount.humanAccountPublic();
    obj[jss::key_type] = to_string (type);

    auto acct = naAccount.getAccountPublic();
    obj[jss::public_key_hex] = strHex(acct.begin(), acct.size());

    return obj;
}