/** * @file * @copyright defined in eos/LICENSE.txt */ #include #include #include #include #include #include #include #include namespace eosio { namespace chain { namespace contracts { time_point chain_initializer::get_chain_start_time() { return genesis.initial_timestamp; } chain_config chain_initializer::get_chain_start_configuration() { return genesis.initial_configuration; } producer_schedule_type chain_initializer::get_chain_start_producers() { producer_schedule_type result; result.producers.push_back( {config::system_account_name, genesis.initial_key} ); return result; } void chain_initializer::register_types(chain_controller& chain, chainbase::database& db) { #define SET_APP_HANDLER( contract, scope, action, nspace ) \ chain._set_apply_handler( #contract, #scope, #action, &BOOST_PP_CAT(contracts::apply_, BOOST_PP_CAT(contract, BOOST_PP_CAT(_,action) ) ) ) SET_APP_HANDLER( eosio, eosio, newaccount, eosio ); SET_APP_HANDLER( eosio, eosio, setcode, eosio ); SET_APP_HANDLER( eosio, eosio, setabi, eosio ); SET_APP_HANDLER( eosio, eosio, updateauth, eosio ); SET_APP_HANDLER( eosio, eosio, deleteauth, eosio ); SET_APP_HANDLER( eosio, eosio, linkauth, eosio ); SET_APP_HANDLER( eosio, eosio, unlinkauth, eosio ); SET_APP_HANDLER( eosio, eosio, onerror, eosio ); SET_APP_HANDLER( eosio, eosio, postrecovery, eosio ); SET_APP_HANDLER( eosio, eosio, passrecovery, eosio ); SET_APP_HANDLER( eosio, eosio, vetorecovery, eosio ); SET_APP_HANDLER( eosio, eosio, canceldelay, eosio ); SET_APP_HANDLER( eosio, eosio, mindelay, eosio ); } abi_def chain_initializer::eos_contract_abi(const abi_def& eosio_system_abi) { abi_def eos_abi(eosio_system_abi); eos_abi.types.push_back( type_def{"account_name","name"} ); eos_abi.types.push_back( type_def{"table_name","name"} ); eos_abi.types.push_back( type_def{"share_type","int64"} ); eos_abi.types.push_back( type_def{"onerror","bytes"} ); eos_abi.types.push_back( type_def{"context_free_type","bytes"} ); eos_abi.types.push_back( type_def{"weight_type","uint16"} ); eos_abi.types.push_back( type_def{"fields","field[]"} ); eos_abi.types.push_back( type_def{"time_point_sec","time"} ); eos_abi.actions.push_back( action_def{name("setcode"), "setcode"} ); eos_abi.actions.push_back( action_def{name("setabi"), "setabi"} ); eos_abi.actions.push_back( action_def{name("linkauth"), "linkauth"} ); eos_abi.actions.push_back( action_def{name("unlinkauth"), "unlinkauth"} ); eos_abi.actions.push_back( action_def{name("updateauth"), "updateauth"} ); eos_abi.actions.push_back( action_def{name("deleteauth"), "deleteauth"} ); eos_abi.actions.push_back( action_def{name("newaccount"), "newaccount"} ); eos_abi.actions.push_back( action_def{name("postrecovery"), "postrecovery"} ); eos_abi.actions.push_back( action_def{name("passrecovery"), "passrecovery"} ); eos_abi.actions.push_back( action_def{name("vetorecovery"), "vetorecovery"} ); eos_abi.actions.push_back( action_def{name("onerror"), "onerror"} ); eos_abi.actions.push_back( action_def{name("onblock"), "onblock"} ); eos_abi.actions.push_back( action_def{name("canceldelay"), "canceldelay"} ); eos_abi.actions.push_back( action_def{name("mindelay"), "mindelay"} ); // ACTION PAYLOADS eos_abi.structs.emplace_back( struct_def { "setcode", "", { {"account", "account_name"}, {"vmtype", "uint8"}, {"vmversion", "uint8"}, {"code", "bytes"} } }); eos_abi.structs.emplace_back( struct_def { "setabi", "", { {"account", "account_name"}, {"abi", "abi_def"} } }); eos_abi.structs.emplace_back( struct_def { "updateauth", "", { {"account", "account_name"}, {"permission", "permission_name"}, {"parent", "permission_name"}, {"data", "authority"}, {"delay", "uint32"} } }); eos_abi.structs.emplace_back( struct_def { "linkauth", "", { {"account", "account_name"}, {"code", "account_name"}, {"type", "action_name"}, {"requirement", "permission_name"}, } }); eos_abi.structs.emplace_back( struct_def { "unlinkauth", "", { {"account", "account_name"}, {"code", "account_name"}, {"type", "action_name"}, } }); eos_abi.structs.emplace_back( struct_def { "deleteauth", "", { {"account", "account_name"}, {"permission", "permission_name"}, } }); eos_abi.structs.emplace_back( struct_def { "newaccount", "", { {"creator", "account_name"}, {"name", "account_name"}, {"owner", "authority"}, {"active", "authority"}, {"recovery", "authority"}, } }); eos_abi.structs.emplace_back( struct_def { "postrecovery", "", { {"account", "account_name"}, {"data", "authority"}, {"memo", "string"}, } }); eos_abi.structs.emplace_back( struct_def { "passrecovery", "", { {"account", "account_name"}, } }); eos_abi.structs.emplace_back( struct_def { "vetorecovery", "", { {"account", "account_name"}, } }); eos_abi.structs.emplace_back( struct_def { "canceldelay", "", { {"sender_id", "uint32"}, } }); eos_abi.structs.emplace_back( struct_def { "mindelay", "", { {"delay", "uint32"}, } }); // DATABASE RECORDS eos_abi.structs.emplace_back( struct_def { "pending_recovery", "", { {"account", "name"}, {"request_id", "uint32"}, {"update", "updateauth"}, {"memo", "string"} } }); eos_abi.tables.emplace_back( table_def { "recovery", "i64", { "account", }, { "name" }, "pending_recovery" }); // abi_def fields eos_abi.structs.emplace_back( struct_def { "field", "", { {"name", "field_name"}, {"type", "type_name"} } }); eos_abi.structs.emplace_back( struct_def { "struct_def", "", { {"name", "type_name"}, {"base", "type_name"}, {"fields", "fields"} } }); eos_abi.structs.emplace_back( struct_def { "permission_level", "", { {"actor", "account_name"}, {"permission", "permission_name"} } }); eos_abi.structs.emplace_back( struct_def { "action", "", { {"account", "account_name"}, {"name", "action_name"}, {"authorization", "permission_level[]"}, {"data", "bytes"} } }); eos_abi.structs.emplace_back( struct_def { "permission_level_weight", "", { {"permission", "permission_level"}, {"weight", "weight_type"} } }); eos_abi.structs.emplace_back( struct_def { "transaction_header", "", { {"expiration", "time_point_sec"}, {"region", "uint16"}, {"ref_block_num", "uint16"}, {"ref_block_prefix", "uint32"}, {"net_usage_words", "varuint32"}, {"kcpu_usage", "varuint32"}, {"delay_sec", "varuint32"} } }); eos_abi.structs.emplace_back( struct_def { "transaction", "transaction_header", { {"context_free_actions", "action[]"}, {"actions", "action[]"} } }); eos_abi.structs.emplace_back( struct_def { "signed_transaction", "transaction", { {"signatures", "signature[]"}, {"context_free_data", "bytes[]"} } }); eos_abi.structs.emplace_back( struct_def { "key_weight", "", { {"key", "public_key"}, {"weight", "weight_type"} } }); eos_abi.structs.emplace_back( struct_def { "authority", "", { {"threshold", "uint32"}, {"keys", "key_weight[]"}, {"accounts", "permission_level_weight[]"} } }); eos_abi.structs.emplace_back( struct_def { "type_def", "", { {"new_type_name", "type_name"}, {"type", "type_name"} } }); eos_abi.structs.emplace_back( struct_def { "action_def", "", { {"name", "action_name"}, {"type", "type_name"} } }); eos_abi.structs.emplace_back( struct_def { "table_def", "", { {"name", "table_name"}, {"index_type", "type_name"}, {"key_names", "field_name[]"}, {"key_types", "type_name[]"}, {"type", "type_name"} } }); eos_abi.structs.emplace_back( struct_def { "abi_def", "", { {"types", "type_def[]"}, {"structs", "struct_def[]"}, {"actions", "action_def[]"}, {"tables", "table_def[]"} } }); eos_abi.structs.emplace_back( struct_def { "block_header", "", { {"previous", "checksum256"}, {"timestamp", "uint32"}, {"transaction_mroot", "checksum256"}, {"action_mroot", "checksum256"}, {"block_mroot", "checksum256"}, {"producer", "account_name"}, {"schedule_version", "uint32"}, {"new_producers", "producer_schedule?"} } }); eos_abi.structs.emplace_back( struct_def { "onblock", "", { {"header", "block_header"} } }); return eos_abi; } void chain_initializer::prepare_database( chain_controller& chain, chainbase::database& db) { /// Reserve id of 0 in permission_index by creating dummy permission_object as the very first object in the index: db.create([&](permission_object& p) { }); /// Create the native contract accounts manually; sadly, we can't run their contracts to make them create themselves auto create_native_account = [this, &chain, &db](account_name name) { db.create([this, &name](account_object& a) { a.name = name; a.creation_date = genesis.initial_timestamp; a.privileged = true; if( name == config::system_account_name ) { a.set_abi(abi_def()); } }); const auto& owner = db.create([&](permission_object& p) { p.owner = name; p.name = "owner"; p.auth.threshold = 1; p.auth.keys.push_back( key_weight{ .key = genesis.initial_key, .weight = 1 } ); }); db.create([&](permission_object& p) { p.owner = name; p.parent = owner.id; p.name = "active"; p.auth.threshold = 1; p.auth.keys.push_back( key_weight{ .key = genesis.initial_key, .weight = 1 } ); }); chain.get_mutable_resource_limits_manager().initialize_account(name); db.create( [&]( auto& pro ) { pro.owner = config::system_account_name; pro.signing_key = genesis.initial_key; }); }; create_native_account(config::system_account_name); // Create special accounts auto create_special_account = [this, &db](account_name name, const auto& owner, const auto& active) { db.create([this, &name](account_object& a) { a.name = name; a.creation_date = genesis.initial_timestamp; }); const auto& owner_permission = db.create([&owner, &name](permission_object& p) { p.name = config::owner_name; p.parent = 0; p.owner = name; p.auth = move(owner); }); db.create([&active, &owner_permission](permission_object& p) { p.name = config::active_name; p.parent = owner_permission.id; p.owner = owner_permission.owner; p.auth = move(active); }); }; auto empty_authority = authority(0, {}, {}); auto active_producers_authority = authority(config::producers_authority_threshold, {}, {}); active_producers_authority.accounts.push_back({{config::system_account_name, config::active_name}, 1}); create_special_account(config::nobody_account_name, empty_authority, empty_authority); create_special_account(config::producers_account_name, empty_authority, active_producers_authority); } } } } // namespace eosio::chain::contracts