From 74223a6bdb075fe99fc19f427fe9edeb5e9de07b Mon Sep 17 00:00:00 2001 From: zhangyaning Date: Sun, 9 Oct 2022 14:38:09 +0800 Subject: [PATCH] ouyeel update --- .dockerignore | 4 + .env | 25 +- .env.test | 2 +- .env.test.local.travis | 0 .gitignore | 7 +- .pryrc | 0 .rspec | 0 .rubocop.yml | 0 .ruby-gemset.sample | 0 .ruby-version | 0 .travis.yml | 4 +- .yardopts | 0 API_DOC.md | 407 ------------------ CHANGELOG.md | 277 ------------ Gemfile | 20 +- Gemfile.lock | 162 +++---- LICENSE | 0 Makefile | 4 +- README-CN.md | 69 --- README.md | 71 --- Rakefile | 0 app/channels/application_cable/channel.rb | 0 app/channels/application_cable/connection.rb | 0 app/controllers/api/blocks_controller.rb | 0 .../api/decode_transactions_controller.rb | 18 + .../api/erc20_transfers_controller.rb | 0 app/controllers/api/event_logs_controller.rb | 0 app/controllers/api/front_end_controller.rb | 75 ++++ app/controllers/api/info_controller.rb | 0 app/controllers/api/ouye_controller.rb | 61 +++ app/controllers/api/platforms_controller.rb | 24 ++ app/controllers/api/query_cita_controller.rb | 77 ++++ app/controllers/api/search_controller.rb | 122 ++++++ app/controllers/api/statistics_controller.rb | 0 app/controllers/api/status_controller.rb | 51 ++- app/controllers/api/storages_controller.rb | 9 + app/controllers/api/sync_errors_controller.rb | 0 .../api/transactions_controller.rb | 0 app/controllers/api/v2/blocks_controller.rb | 0 .../api/v2/transactions_controller.rb | 0 app/controllers/application_controller.rb | 38 +- app/controllers/cita_controller.rb | 0 app/controllers/concerns/.keep | 0 app/jobs/application_job.rb | 0 app/mailers/application_mailer.rb | 0 app/models/application_record.rb | 0 app/models/backstage_personnel.rb | 15 + app/models/block.rb | 0 app/models/circulation_tongbao.rb | 109 +++++ app/models/cita_sync/api.rb | 0 app/models/cita_sync/persist.rb | 25 +- app/models/concerns/.keep | 0 app/models/contract_abi.rb | 102 +++++ app/models/decode_transaction.rb | 58 +++ app/models/erc20_transfer.rb | 14 +- app/models/event_log.rb | 2 +- app/models/event_log_processor.rb | 0 app/models/financing_tongbao.rb | 115 +++++ app/models/freeze_item.rb | 62 +++ app/models/freeze_tongbao.rb | 39 ++ app/models/institution.rb | 79 ++++ app/models/lock_credit.rb | 23 + app/models/lock_tongbao.rb | 76 ++++ app/models/message.rb | 2 +- app/models/open_tongbao.rb | 183 ++++++++ app/models/operator.rb | 14 + app/models/platform.rb | 15 + app/models/pledge_tongbao.rb | 83 ++++ app/models/storage_record.rb | 7 + app/models/sync_error.rb | 0 app/models/sync_info.rb | 0 app/models/tongbao.rb | 74 ++++ app/models/transaction.rb | 38 +- app/models/validator_cache.rb | 0 app/serializers/api/block_serializer.rb | 0 .../api/erc20_transfer_serializer.rb | 0 app/serializers/api/event_log_serializer.rb | 0 app/serializers/api/sync_error_serializer.rb | 0 app/serializers/api/transaction_serializer.rb | 0 app/serializers/block_serializer.rb | 0 app/serializers/transaction_serializer.rb | 0 app/utils/decode_utils.rb | 28 ++ app/utils/hex_utils.rb | 0 app/views/api/ouye/credit_list.json.jbuilder | 13 + .../api/ouye/ent_open_tongbaos.json.jbuilder | 14 + .../api/ouye/tongbao_detail.json.jbuilder | 11 + app/views/api/ouye/tongbao_list.json.jbuilder | 13 + app/views/layouts/mailer.html.erb | 0 app/views/layouts/mailer.text.erb | 0 app/workers/build_storage_worker.rb | 102 +++++ app/workers/push_storage_worker.rb | 43 ++ app/workers/save_block_worker.rb | 0 app/workers/save_decode_transaction_worker.rb | 16 + app/workers/save_decoded_info_worker.rb | 145 +++++++ ..._worker.rb => save_erc_transfer_worker.rb} | 4 +- app/workers/save_event_logs_worker.rb | 0 app/workers/save_transaction_worker.rb | 0 bin/cita-cli | Bin 0 -> 14174248 bytes bin/mac/cita-cli | Bin 0 -> 9972364 bytes config.ru | 5 + config/application.rb | 2 + config/boot.rb | 0 config/cable.yml | 0 config/customs/event_log.yml.sample | 0 config/database.yml | 0 config/deploy.rb | 0 config/deploy/dev.rb | 0 config/deploy/production.rb | 0 config/deploy/staging.rb | 0 config/environment.rb | 0 config/environments/development.rb | 0 config/environments/production.rb | 4 +- config/environments/test.rb | 0 .../initializers/active_model_serializers.rb | 0 .../application_controller_renderer.rb | 0 config/initializers/backtrace_silencers.rb | 0 config/initializers/contract.rb | 26 ++ config/initializers/cors.rb | 0 config/initializers/custom_exporter.rb | 61 +++ .../initializers/filter_parameter_logging.rb | 0 config/initializers/inflections.rb | 0 config/initializers/kaminari_config.rb | 0 config/initializers/mime_types.rb | 0 config/initializers/numeric.rb | 10 + config/initializers/redis.rb | 0 config/initializers/rpc.rb | 18 + config/initializers/sidekiq.rb | 1 + config/initializers/transaction_signer.rb | 48 +++ config/initializers/wrap_parameters.rb | 0 config/locales/en.yml | 0 config/nginx.conf.sample | 0 config/puma.docker.rb | 0 config/puma.rb.sample | 0 config/redis.yml | 0 config/routes.rb | 28 +- config/secrets.yml | 0 config/sidekiq.yml | 5 +- config/spring.rb | 0 config/storage.yml | 0 db/migrate/20180619034736_create_blocks.rb | 0 .../20180619061147_create_transactions.rb | 0 db/migrate/20180704082334_create_meta_data.rb | 0 db/migrate/20180704092420_create_balances.rb | 0 db/migrate/20180705032658_create_abis.rb | 0 ...80706061134_add_token_name_to_meta_data.rb | 0 ...20180706063551_change_height_to_balance.rb | 0 ...9091027_add_transaction_count_to_blocks.rb | 0 ...80711075733_add_columns_to_transactions.rb | 0 .../20180807030924_create_sync_errors.rb | 0 .../20180807073702_add_data_to_sync_errors.rb | 0 .../20180816073015_add_index_to_blocks.rb | 0 .../20180817090233_create_sync_infos.rb | 0 db/migrate/20180823023239_drop_meta_data.rb | 0 .../20180903024536_create_validator_caches.rb | 0 .../20180917030158_create_event_logs.rb | 0 ...0917092311_add_references_to_event_logs.rb | 0 .../20180919033713_create_erc20_transfers.rb | 0 ...22937_add_error_message_to_transactions.rb | 0 ...81101035658_add_version_to_transactions.rb | 0 ...95358_rename_quota_used_to_transactions.rb | 0 ...70637_add_block_hash_to_erc20_transfers.rb | 0 ...1220074930_change_primary_key_to_blocks.rb | 0 ...5708_change_primary_key_to_transactions.rb | 0 ...0083423_change_index_type_to_event_logs.rb | 0 ...091018_add_log_index_to_erc20_transfers.rb | 0 ...092401_change_primary_key_to_event_logs.rb | 0 ...8_change_primary_key_to_erc20_transfers.rb | 0 ...220093106_remove_fkey_from_transactions.rb | 0 ...81220093546_remove_fkey_from_event_logs.rb | 0 ...093811_remove_fkey_from_erc20_transfers.rb | 0 db/migrate/20181220094434_rename_cita_hash.rb | 0 ...075716_change_num_types_to_transactions.rb | 0 ...1226101230_remove_str_from_transactions.rb | 0 ...26101553_change_num_types_to_event_logs.rb | 0 ...181226102120_remove_str_from_event_logs.rb | 0 ...501_change_num_types_to_erc20_transfers.rb | 0 ...6103138_remove_str_from_erc20_transfers.rb | 0 .../20181227091201_add_some_info_to_blocks.rb | 0 ...229030703_add_timestamp_to_transactions.rb | 0 db/migrate/20190103060058_remove_balances.rb | 0 db/migrate/20190103060302_remove_abis.rb | 0 ...190717031451_create_decode_transactions.rb | 17 + .../20190721034633_create_contract_abis.rb | 14 + ...90727091301_create_backstage_personnels.rb | 13 + .../20190731092734_create_institutions.rb | 36 ++ db/migrate/20190805032247_create_operators.rb | 15 + .../20190805062901_create_open_tongbaos.rb | 55 +++ ...90806060345_create_circulation_tongbaos.rb | 37 ++ ...0190806075150_create_financing_tongbaos.rb | 43 ++ db/migrate/20190807053710_create_tongbaos.rb | 32 ++ .../20190903021547_create_lock_credits.rb | 19 + ...0190903054344_add_conract_name_to_erc20.rb | 5 + .../20190905074851_create_lock_tongbaos.rb | 21 + .../20190906033016_create_freeze_tongbaos.rb | 21 + ...12020735_add_open_limit_to_institutions.rb | 5 + ...15548_add_invoice_info_to_open_tongbaos.rb | 7 + .../20200601091229_create_storage_records.rb | 19 + .../20200708065237_create_freeze_items.rb | 20 + db/migrate/20200828021930_create_platforms.rb | 15 + ...dd_index_credit_balance_for_institution.rb | 5 + .../20201209033501_create_pledge_tongbaos.rb | 32 ++ ...1225032358_add_store_index_for_storages.rb | 5 + ...2114_add_contract_version_to_decode_txs.rb | 5 + ...210322062003_add_auth_info_to_platforms.rb | 6 + db/schema.rb | 341 ++++++++++++++- db/seeds.rb | 12 + docker-compose.yml | 39 +- docker-compose.yml.sample | 45 ++ docker/app/Dockerfile | 25 +- docker/web/Dockerfile | 1 + docker/web/nginx.conf | 6 +- docs/tech_stack.md | 63 --- lib/assets/.keep | 0 lib/scripts/20190711_create_manager.rb | 64 +++ lib/scripts/20190711_try_create_manager.rb | 32 ++ lib/scripts/20190712_parse_event_log.rb | 57 +++ .../20190712_parse_transaction_args.rb | 17 + lib/scripts/20190718_call_contract.rb | 13 + .../20191012_update_ents_open_limit.rb | 11 + lib/scripts/20191227_call_native_contract.rb | 39 ++ lib/scripts/20200103_call_ecgmult.rb | 35 ++ lib/scripts/20200106_call_add.rb | 56 +++ lib/scripts/20200114_call_range.rb | 42 ++ lib/scripts/20200304_set_tongbao_lock_ents.rb | 39 ++ lib/scripts/20200602_sync_storage.rb | 6 + lib/sync_control.rb | 21 +- lib/tasks/.keep | 0 lib/tasks/blocks.rake | 0 lib/tasks/daemons.rake | 27 +- lib/tasks/deploy_contract.rake | 109 +++++ lib/tasks/event_log.rake | 0 lib/tasks/event_logs.rake | 0 lib/tasks/transactions.rake | 0 lib/tasks/zero18.rake | 0 lib/tasks/zero20.rake | 0 log/.keep | 0 public/index.html | 1 + public/robots.txt | 1 - .../app.f816b828a12211d631ddec7e83109ead.css | 2 + ...p.f816b828a12211d631ddec7e83109ead.css.map | 1 + .../fonts/SourceHanSansSC-Regular.01c0133.otf | Bin 0 -> 17849568 bytes .../static/fonts/element-icons.535877f.woff | Bin 0 -> 28200 bytes public/static/fonts/element-icons.732389d.ttf | Bin 0 -> 55956 bytes public/static/js/app.4a9dbefa338f7e81d8e5.js | 2 + .../static/js/app.4a9dbefa338f7e81d8e5.js.map | 1 + .../js/manifest.2ae2e69a05c33dfc65f8.js | 2 + .../js/manifest.2ae2e69a05c33dfc65f8.js.map | 1 + .../static/js/vendor.fe28beabe98814320d61.js | 40 ++ .../js/vendor.fe28beabe98814320d61.js.map | 1 + spec/config/customs/contracts.yml | 0 .../controllers/api/blocks_controller_spec.rb | 0 .../api/erc20_transfers_controller_spec.rb | 0 .../api/event_logs_controller_spec.rb | 0 spec/controllers/api/info_controller_spec.rb | 0 .../api/statistics_controller_spec.rb | 0 .../controllers/api/status_controller_spec.rb | 0 .../api/sync_errors_controller_spec.rb | 0 .../api/transactions_controller_spec.rb | 0 .../api/v2/blocks_controller_spec.rb | 0 .../api/v2/transactions_controller_spec.rb | 0 .../application_controller_spec.rb | 0 spec/controllers/cita_controller_spec.rb | 0 spec/factories/blocks.rb | 0 spec/factories/erc20_transfers.rb | 0 spec/factories/event_logs.rb | 0 spec/factories/sync_errors.rb | 0 spec/factories/sync_infos.rb | 0 spec/factories/transactions.rb | 0 spec/factories/validator_caches.rb | 0 spec/models/block_spec.rb | 0 spec/models/cita_sync/api_spec.rb | 0 spec/models/cita_sync/persist_spec.rb | 0 spec/models/erc20_transfer_spec.rb | 0 spec/models/event_log_processor_spec.rb | 0 spec/models/event_log_spec.rb | 0 spec/models/message_spec.rb | 0 spec/models/sync_error_spec.rb | 0 spec/models/sync_info_spec.rb | 0 spec/models/validator_cache_spec.rb | 0 spec/rails_helper.rb | 3 + spec/spec_helper.rb | 0 spec/supports/block_mock_support.rb | 0 spec/supports/event_log_mock_support.rb | 0 spec/utils/decode_utils_spec.rb | 0 spec/utils/hex_utils_spec.rb | 0 .../save_erc20_transfer_worker_spec.rb | 3 - spec/workers/save_event_logs_worker_spec.rb | 0 spec/workers/save_transaction_worker_spec.rb | 0 tmp/.keep | 0 tmp/pids/.keep | 0 vendor/.keep | 0 291 files changed, 3798 insertions(+), 1066 deletions(-) mode change 100644 => 100755 .dockerignore mode change 100644 => 100755 .env mode change 100644 => 100755 .env.test mode change 100644 => 100755 .env.test.local.travis mode change 100644 => 100755 .gitignore mode change 100644 => 100755 .pryrc mode change 100644 => 100755 .rspec mode change 100644 => 100755 .rubocop.yml mode change 100644 => 100755 .ruby-gemset.sample mode change 100644 => 100755 .ruby-version mode change 100644 => 100755 .travis.yml mode change 100644 => 100755 .yardopts delete mode 100644 API_DOC.md delete mode 100644 CHANGELOG.md mode change 100644 => 100755 Gemfile mode change 100644 => 100755 Gemfile.lock mode change 100644 => 100755 LICENSE mode change 100644 => 100755 Makefile mode change 100644 => 100755 README-CN.md mode change 100644 => 100755 README.md mode change 100644 => 100755 Rakefile mode change 100644 => 100755 app/channels/application_cable/channel.rb mode change 100644 => 100755 app/channels/application_cable/connection.rb mode change 100644 => 100755 app/controllers/api/blocks_controller.rb create mode 100755 app/controllers/api/decode_transactions_controller.rb mode change 100644 => 100755 app/controllers/api/erc20_transfers_controller.rb mode change 100644 => 100755 app/controllers/api/event_logs_controller.rb create mode 100755 app/controllers/api/front_end_controller.rb mode change 100644 => 100755 app/controllers/api/info_controller.rb create mode 100755 app/controllers/api/ouye_controller.rb create mode 100755 app/controllers/api/platforms_controller.rb create mode 100755 app/controllers/api/query_cita_controller.rb create mode 100755 app/controllers/api/search_controller.rb mode change 100644 => 100755 app/controllers/api/statistics_controller.rb mode change 100644 => 100755 app/controllers/api/status_controller.rb create mode 100755 app/controllers/api/storages_controller.rb mode change 100644 => 100755 app/controllers/api/sync_errors_controller.rb mode change 100644 => 100755 app/controllers/api/transactions_controller.rb mode change 100644 => 100755 app/controllers/api/v2/blocks_controller.rb mode change 100644 => 100755 app/controllers/api/v2/transactions_controller.rb mode change 100644 => 100755 app/controllers/application_controller.rb mode change 100644 => 100755 app/controllers/cita_controller.rb mode change 100644 => 100755 app/controllers/concerns/.keep mode change 100644 => 100755 app/jobs/application_job.rb mode change 100644 => 100755 app/mailers/application_mailer.rb mode change 100644 => 100755 app/models/application_record.rb create mode 100755 app/models/backstage_personnel.rb mode change 100644 => 100755 app/models/block.rb create mode 100755 app/models/circulation_tongbao.rb mode change 100644 => 100755 app/models/cita_sync/api.rb mode change 100644 => 100755 app/models/cita_sync/persist.rb mode change 100644 => 100755 app/models/concerns/.keep create mode 100755 app/models/contract_abi.rb create mode 100755 app/models/decode_transaction.rb mode change 100644 => 100755 app/models/erc20_transfer.rb mode change 100644 => 100755 app/models/event_log.rb mode change 100644 => 100755 app/models/event_log_processor.rb create mode 100755 app/models/financing_tongbao.rb create mode 100755 app/models/freeze_item.rb create mode 100755 app/models/freeze_tongbao.rb create mode 100755 app/models/institution.rb create mode 100755 app/models/lock_credit.rb create mode 100755 app/models/lock_tongbao.rb mode change 100644 => 100755 app/models/message.rb create mode 100755 app/models/open_tongbao.rb create mode 100755 app/models/operator.rb create mode 100755 app/models/platform.rb create mode 100755 app/models/pledge_tongbao.rb create mode 100755 app/models/storage_record.rb mode change 100644 => 100755 app/models/sync_error.rb mode change 100644 => 100755 app/models/sync_info.rb create mode 100755 app/models/tongbao.rb mode change 100644 => 100755 app/models/transaction.rb mode change 100644 => 100755 app/models/validator_cache.rb mode change 100644 => 100755 app/serializers/api/block_serializer.rb mode change 100644 => 100755 app/serializers/api/erc20_transfer_serializer.rb mode change 100644 => 100755 app/serializers/api/event_log_serializer.rb mode change 100644 => 100755 app/serializers/api/sync_error_serializer.rb mode change 100644 => 100755 app/serializers/api/transaction_serializer.rb mode change 100644 => 100755 app/serializers/block_serializer.rb mode change 100644 => 100755 app/serializers/transaction_serializer.rb mode change 100644 => 100755 app/utils/decode_utils.rb mode change 100644 => 100755 app/utils/hex_utils.rb create mode 100755 app/views/api/ouye/credit_list.json.jbuilder create mode 100755 app/views/api/ouye/ent_open_tongbaos.json.jbuilder create mode 100755 app/views/api/ouye/tongbao_detail.json.jbuilder create mode 100755 app/views/api/ouye/tongbao_list.json.jbuilder mode change 100644 => 100755 app/views/layouts/mailer.html.erb mode change 100644 => 100755 app/views/layouts/mailer.text.erb create mode 100755 app/workers/build_storage_worker.rb create mode 100755 app/workers/push_storage_worker.rb mode change 100644 => 100755 app/workers/save_block_worker.rb create mode 100755 app/workers/save_decode_transaction_worker.rb create mode 100755 app/workers/save_decoded_info_worker.rb rename app/workers/{save_erc20_transfer_worker.rb => save_erc_transfer_worker.rb} (58%) mode change 100644 => 100755 mode change 100644 => 100755 app/workers/save_event_logs_worker.rb mode change 100644 => 100755 app/workers/save_transaction_worker.rb create mode 100755 bin/cita-cli create mode 100755 bin/mac/cita-cli mode change 100644 => 100755 config.ru mode change 100644 => 100755 config/application.rb mode change 100644 => 100755 config/boot.rb mode change 100644 => 100755 config/cable.yml mode change 100644 => 100755 config/customs/event_log.yml.sample mode change 100644 => 100755 config/database.yml mode change 100644 => 100755 config/deploy.rb mode change 100644 => 100755 config/deploy/dev.rb mode change 100644 => 100755 config/deploy/production.rb mode change 100644 => 100755 config/deploy/staging.rb mode change 100644 => 100755 config/environment.rb mode change 100644 => 100755 config/environments/development.rb mode change 100644 => 100755 config/environments/production.rb mode change 100644 => 100755 config/environments/test.rb mode change 100644 => 100755 config/initializers/active_model_serializers.rb mode change 100644 => 100755 config/initializers/application_controller_renderer.rb mode change 100644 => 100755 config/initializers/backtrace_silencers.rb create mode 100755 config/initializers/contract.rb mode change 100644 => 100755 config/initializers/cors.rb create mode 100755 config/initializers/custom_exporter.rb mode change 100644 => 100755 config/initializers/filter_parameter_logging.rb mode change 100644 => 100755 config/initializers/inflections.rb mode change 100644 => 100755 config/initializers/kaminari_config.rb mode change 100644 => 100755 config/initializers/mime_types.rb create mode 100755 config/initializers/numeric.rb mode change 100644 => 100755 config/initializers/redis.rb create mode 100755 config/initializers/rpc.rb mode change 100644 => 100755 config/initializers/sidekiq.rb create mode 100755 config/initializers/transaction_signer.rb mode change 100644 => 100755 config/initializers/wrap_parameters.rb mode change 100644 => 100755 config/locales/en.yml mode change 100644 => 100755 config/nginx.conf.sample mode change 100644 => 100755 config/puma.docker.rb mode change 100644 => 100755 config/puma.rb.sample mode change 100644 => 100755 config/redis.yml mode change 100644 => 100755 config/routes.rb mode change 100644 => 100755 config/secrets.yml mode change 100644 => 100755 config/sidekiq.yml mode change 100644 => 100755 config/spring.rb mode change 100644 => 100755 config/storage.yml mode change 100644 => 100755 db/migrate/20180619034736_create_blocks.rb mode change 100644 => 100755 db/migrate/20180619061147_create_transactions.rb mode change 100644 => 100755 db/migrate/20180704082334_create_meta_data.rb mode change 100644 => 100755 db/migrate/20180704092420_create_balances.rb mode change 100644 => 100755 db/migrate/20180705032658_create_abis.rb mode change 100644 => 100755 db/migrate/20180706061134_add_token_name_to_meta_data.rb mode change 100644 => 100755 db/migrate/20180706063551_change_height_to_balance.rb mode change 100644 => 100755 db/migrate/20180709091027_add_transaction_count_to_blocks.rb mode change 100644 => 100755 db/migrate/20180711075733_add_columns_to_transactions.rb mode change 100644 => 100755 db/migrate/20180807030924_create_sync_errors.rb mode change 100644 => 100755 db/migrate/20180807073702_add_data_to_sync_errors.rb mode change 100644 => 100755 db/migrate/20180816073015_add_index_to_blocks.rb mode change 100644 => 100755 db/migrate/20180817090233_create_sync_infos.rb mode change 100644 => 100755 db/migrate/20180823023239_drop_meta_data.rb mode change 100644 => 100755 db/migrate/20180903024536_create_validator_caches.rb mode change 100644 => 100755 db/migrate/20180917030158_create_event_logs.rb mode change 100644 => 100755 db/migrate/20180917092311_add_references_to_event_logs.rb mode change 100644 => 100755 db/migrate/20180919033713_create_erc20_transfers.rb mode change 100644 => 100755 db/migrate/20181009022937_add_error_message_to_transactions.rb mode change 100644 => 100755 db/migrate/20181101035658_add_version_to_transactions.rb mode change 100644 => 100755 db/migrate/20181101095358_rename_quota_used_to_transactions.rb mode change 100644 => 100755 db/migrate/20181220070637_add_block_hash_to_erc20_transfers.rb mode change 100644 => 100755 db/migrate/20181220074930_change_primary_key_to_blocks.rb mode change 100644 => 100755 db/migrate/20181220075708_change_primary_key_to_transactions.rb mode change 100644 => 100755 db/migrate/20181220083423_change_index_type_to_event_logs.rb mode change 100644 => 100755 db/migrate/20181220091018_add_log_index_to_erc20_transfers.rb mode change 100644 => 100755 db/migrate/20181220092401_change_primary_key_to_event_logs.rb mode change 100644 => 100755 db/migrate/20181220092458_change_primary_key_to_erc20_transfers.rb mode change 100644 => 100755 db/migrate/20181220093106_remove_fkey_from_transactions.rb mode change 100644 => 100755 db/migrate/20181220093546_remove_fkey_from_event_logs.rb mode change 100644 => 100755 db/migrate/20181220093811_remove_fkey_from_erc20_transfers.rb mode change 100644 => 100755 db/migrate/20181220094434_rename_cita_hash.rb mode change 100644 => 100755 db/migrate/20181226075716_change_num_types_to_transactions.rb mode change 100644 => 100755 db/migrate/20181226101230_remove_str_from_transactions.rb mode change 100644 => 100755 db/migrate/20181226101553_change_num_types_to_event_logs.rb mode change 100644 => 100755 db/migrate/20181226102120_remove_str_from_event_logs.rb mode change 100644 => 100755 db/migrate/20181226102501_change_num_types_to_erc20_transfers.rb mode change 100644 => 100755 db/migrate/20181226103138_remove_str_from_erc20_transfers.rb mode change 100644 => 100755 db/migrate/20181227091201_add_some_info_to_blocks.rb mode change 100644 => 100755 db/migrate/20181229030703_add_timestamp_to_transactions.rb mode change 100644 => 100755 db/migrate/20190103060058_remove_balances.rb mode change 100644 => 100755 db/migrate/20190103060302_remove_abis.rb create mode 100755 db/migrate/20190717031451_create_decode_transactions.rb create mode 100755 db/migrate/20190721034633_create_contract_abis.rb create mode 100755 db/migrate/20190727091301_create_backstage_personnels.rb create mode 100755 db/migrate/20190731092734_create_institutions.rb create mode 100755 db/migrate/20190805032247_create_operators.rb create mode 100755 db/migrate/20190805062901_create_open_tongbaos.rb create mode 100755 db/migrate/20190806060345_create_circulation_tongbaos.rb create mode 100755 db/migrate/20190806075150_create_financing_tongbaos.rb create mode 100755 db/migrate/20190807053710_create_tongbaos.rb create mode 100755 db/migrate/20190903021547_create_lock_credits.rb create mode 100755 db/migrate/20190903054344_add_conract_name_to_erc20.rb create mode 100755 db/migrate/20190905074851_create_lock_tongbaos.rb create mode 100755 db/migrate/20190906033016_create_freeze_tongbaos.rb create mode 100755 db/migrate/20191012020735_add_open_limit_to_institutions.rb create mode 100755 db/migrate/20200326015548_add_invoice_info_to_open_tongbaos.rb create mode 100755 db/migrate/20200601091229_create_storage_records.rb create mode 100755 db/migrate/20200708065237_create_freeze_items.rb create mode 100755 db/migrate/20200828021930_create_platforms.rb create mode 100755 db/migrate/20200923071339_add_index_credit_balance_for_institution.rb create mode 100755 db/migrate/20201209033501_create_pledge_tongbaos.rb create mode 100755 db/migrate/20201225032358_add_store_index_for_storages.rb create mode 100755 db/migrate/20210126082114_add_contract_version_to_decode_txs.rb create mode 100755 db/migrate/20210322062003_add_auth_info_to_platforms.rb mode change 100644 => 100755 db/schema.rb mode change 100644 => 100755 db/seeds.rb mode change 100644 => 100755 docker-compose.yml create mode 100755 docker-compose.yml.sample mode change 100644 => 100755 docker/app/Dockerfile mode change 100644 => 100755 docker/web/Dockerfile mode change 100644 => 100755 docker/web/nginx.conf delete mode 100644 docs/tech_stack.md mode change 100644 => 100755 lib/assets/.keep create mode 100755 lib/scripts/20190711_create_manager.rb create mode 100755 lib/scripts/20190711_try_create_manager.rb create mode 100755 lib/scripts/20190712_parse_event_log.rb create mode 100755 lib/scripts/20190712_parse_transaction_args.rb create mode 100755 lib/scripts/20190718_call_contract.rb create mode 100755 lib/scripts/20191012_update_ents_open_limit.rb create mode 100755 lib/scripts/20191227_call_native_contract.rb create mode 100755 lib/scripts/20200103_call_ecgmult.rb create mode 100755 lib/scripts/20200106_call_add.rb create mode 100755 lib/scripts/20200114_call_range.rb create mode 100755 lib/scripts/20200304_set_tongbao_lock_ents.rb create mode 100755 lib/scripts/20200602_sync_storage.rb mode change 100644 => 100755 lib/sync_control.rb mode change 100644 => 100755 lib/tasks/.keep mode change 100644 => 100755 lib/tasks/blocks.rake mode change 100644 => 100755 lib/tasks/daemons.rake create mode 100755 lib/tasks/deploy_contract.rake mode change 100644 => 100755 lib/tasks/event_log.rake mode change 100644 => 100755 lib/tasks/event_logs.rake mode change 100644 => 100755 lib/tasks/transactions.rake mode change 100644 => 100755 lib/tasks/zero18.rake mode change 100644 => 100755 lib/tasks/zero20.rake mode change 100644 => 100755 log/.keep create mode 100755 public/index.html delete mode 100644 public/robots.txt create mode 100755 public/static/css/app.f816b828a12211d631ddec7e83109ead.css create mode 100755 public/static/css/app.f816b828a12211d631ddec7e83109ead.css.map create mode 100755 public/static/fonts/SourceHanSansSC-Regular.01c0133.otf create mode 100755 public/static/fonts/element-icons.535877f.woff create mode 100755 public/static/fonts/element-icons.732389d.ttf create mode 100755 public/static/js/app.4a9dbefa338f7e81d8e5.js create mode 100755 public/static/js/app.4a9dbefa338f7e81d8e5.js.map create mode 100755 public/static/js/manifest.2ae2e69a05c33dfc65f8.js create mode 100755 public/static/js/manifest.2ae2e69a05c33dfc65f8.js.map create mode 100755 public/static/js/vendor.fe28beabe98814320d61.js create mode 100755 public/static/js/vendor.fe28beabe98814320d61.js.map mode change 100644 => 100755 spec/config/customs/contracts.yml mode change 100644 => 100755 spec/controllers/api/blocks_controller_spec.rb mode change 100644 => 100755 spec/controllers/api/erc20_transfers_controller_spec.rb mode change 100644 => 100755 spec/controllers/api/event_logs_controller_spec.rb mode change 100644 => 100755 spec/controllers/api/info_controller_spec.rb mode change 100644 => 100755 spec/controllers/api/statistics_controller_spec.rb mode change 100644 => 100755 spec/controllers/api/status_controller_spec.rb mode change 100644 => 100755 spec/controllers/api/sync_errors_controller_spec.rb mode change 100644 => 100755 spec/controllers/api/transactions_controller_spec.rb mode change 100644 => 100755 spec/controllers/api/v2/blocks_controller_spec.rb mode change 100644 => 100755 spec/controllers/api/v2/transactions_controller_spec.rb mode change 100644 => 100755 spec/controllers/application_controller_spec.rb mode change 100644 => 100755 spec/controllers/cita_controller_spec.rb mode change 100644 => 100755 spec/factories/blocks.rb mode change 100644 => 100755 spec/factories/erc20_transfers.rb mode change 100644 => 100755 spec/factories/event_logs.rb mode change 100644 => 100755 spec/factories/sync_errors.rb mode change 100644 => 100755 spec/factories/sync_infos.rb mode change 100644 => 100755 spec/factories/transactions.rb mode change 100644 => 100755 spec/factories/validator_caches.rb mode change 100644 => 100755 spec/models/block_spec.rb mode change 100644 => 100755 spec/models/cita_sync/api_spec.rb mode change 100644 => 100755 spec/models/cita_sync/persist_spec.rb mode change 100644 => 100755 spec/models/erc20_transfer_spec.rb mode change 100644 => 100755 spec/models/event_log_processor_spec.rb mode change 100644 => 100755 spec/models/event_log_spec.rb mode change 100644 => 100755 spec/models/message_spec.rb mode change 100644 => 100755 spec/models/sync_error_spec.rb mode change 100644 => 100755 spec/models/sync_info_spec.rb mode change 100644 => 100755 spec/models/validator_cache_spec.rb mode change 100644 => 100755 spec/rails_helper.rb mode change 100644 => 100755 spec/spec_helper.rb mode change 100644 => 100755 spec/supports/block_mock_support.rb mode change 100644 => 100755 spec/supports/event_log_mock_support.rb mode change 100644 => 100755 spec/utils/decode_utils_spec.rb mode change 100644 => 100755 spec/utils/hex_utils_spec.rb delete mode 100644 spec/workers/save_erc20_transfer_worker_spec.rb mode change 100644 => 100755 spec/workers/save_event_logs_worker_spec.rb mode change 100644 => 100755 spec/workers/save_transaction_worker_spec.rb mode change 100644 => 100755 tmp/.keep create mode 100755 tmp/pids/.keep mode change 100644 => 100755 vendor/.keep diff --git a/.dockerignore b/.dockerignore old mode 100644 new mode 100755 index d111f8a..4d0fe0a --- a/.dockerignore +++ b/.dockerignore @@ -3,3 +3,7 @@ tmp docker/data docker/redis +/log/* +!/log/.keep +.DS_Store +TAGS \ No newline at end of file diff --git a/.env b/.env old mode 100644 new mode 100755 index 21b3070..81f4dd6 --- a/.env +++ b/.env @@ -1,15 +1,10 @@ # override items in .env.local(.env.{env}.local) if you need -# app config - -# set log level, use "info" for production by default, use "debug" for development -# RAILS_LOG_LEVEL="info" - # database config # "db" for docker inside database, "host.docker.internal" for host database(only work for mac and windows for docker 18.03+) DB_HOST="db" DB_PORT=5432 -DB_POOL=64 +DB_POOL=25 DB_USERNAME="postgres" DB_PASSWORD="postgres" DB_NAME_DEV="re-birth_development" @@ -33,12 +28,28 @@ SECRET_KEY_BASE="dee66a8ef3281bc6bd74a5637ede4d846c455df93ca0d6c098da1d52b65dda8 # cita config # set default to localhost -CITA_URL="http://localhost:1337/" +CITA_URL="http://localhost:1337/" #需部署cita-cli 并 switch --algorithm sm2 CITA_WS_PORT="4337" # "ws" or "wss", if blank, http => ws, https => wss CITA_WS_PROTOCOL="" +PUB_CITA_URL="http://192.168.1.90:1337/" # block config SAVE_BLOCKS="true" # true or false, only "false" will not save blocks. LOOP_INTERVAL="1" + +# PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMxr8bRMGBu8Y1IguTG/6AIA6m\nHeccdKfbe4kZHL1pNEcF52uGyCREKEAq/y1Ewao8PTQT5CZEdCSoQkKvOyywlRuD\nM6ssZwPAk9Angxd9xxZlVQyu/fDSi30YtUAJQ+q94eNj6YuSo2WBQHXxO9FtSloj\ntCLZSkmS9hF7r6CiRwIDAQAB\n-----END PUBLIC KEY-----\n" + +PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCZbFhEhbZoL9YeFX5qwIAT4WQmKKi6rxb3+53CYoOsPvjW0M3dlV8oEedzi79DMROONJ3usfp83XHzX2iUuVl5GXqK/c/1PIdh5DMWILLb8qlK9MtyYVRnC0I2xI81McnygLbNZAdJ4+pJvjoq3ugZ/COqK4JP0xxOnh/J4cerOwIDAQAB\n-----END PUBLIC KEY-----" + + # [possible values: secp256k1, ed25519, sm2] +ALGORITHM="sm2" +CITA_CLI_PATH="bin/cita-cli" +#逗号分割组,冒号分割地址私钥 +STORAGE_AUTH_PUBKEYS="0x2ed5b38d63d3556af46a12ac01f8c022571647f934e764cf0f51bc662dcb0dc8d52d5aac727de00b9710df6a87746770260ce4b36c17c49d68914462d85d7e18" +STORAGE_FRONT_URL="http://192.168.2.23:10070/dataEvidence/evidence/data/save" +STORAGE_CHAIN_ID="bc002" +STORAGE_CALLBACK_URL="http://192.168.1.13:8888/api/storages/callback/" +STORAGE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAIxIb4ak1pOzVQRfgiYuAjioVk2sFBdztpAv81qCGTWjrsnEBTG89oDFMTOGyHupSaHbCmRC5pWSnyPERR6k7tbZpShLYx42oR8IJ001SbAfki7aRfUNLWeY2ox20zdC/c6ZLF1plnhfwP1jfB4dH3PUkq+XTXWdzyxzRX/pBAYDAgMBAAECgYEAiaeGsJPN7295DGp/9uEM0vX0ghFKQd0NFx3GaVjiTe1JVbmg8zaemKtnZU1sK1Rp6YZcAxhW1gzjViCBRtnHdtSgPh8SGeaGsG/EC4p7PJxvrUO/P7C0fsuG5gyQz0IC1NZVovQeJGujB8P7M9zw7Ea32waTVd4uYv4vm+ta0pECQQDuexnixOG0bWzqYZf335w0JHfMBIti5K/PBgMGLhu5q3yrbkH0iGW2XI+wUIfl2ebkRNsczqgO10PV2lqaqg6JAkEAlpac+Jof1Byy7jhPNuH+lX6MB5wLoJwqP2hjg2Yi5MOCmNe14ndh3j9PY+Kbld0kSxnixI1lDY9njkTvDVmtKwJBANOxBI5u1Ce0Rs1bamnG3cLPaGP62LwlYgZ0QLT4svXCyvzl97gYZ6lUStxo7+lR3wpcMOBGdZoO7hFkLa9DK3kCQA2Ka4D7MuN61SgQjibsOV0t7N9+S5lckXv0Igadt4OEhQjDVMqRW46FeNkNdloKcYoDQN3VrQGEJJapYil8J9MCQQDbaOybrR/paRnzSRqc9OL5BEnCO0kgw4/u+5+wkKU5i8HwD46wt3jneLx3k1+547X029oiNx/eieSMz7f/d1W1\n-----END PRIVATE KEY-----" +STORAGE_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCMSG+GpNaTs1UEX4ImLgI4qFZNrBQXc7aQL/Naghk1o67JxAUxvPaAxTEzhsh7qUmh2wpkQuaVkp8jxEUepO7W2aUoS2MeNqEfCCdNNUmwH5Iu2kX1DS1nmNqMdtM3Qv3OmSxdaZZ4X8D9Y3weHR9z1JKvl011nc8sc0V/6QQGAwIDAQAB\n-----END PUBLIC KEY-----" \ No newline at end of file diff --git a/.env.test b/.env.test old mode 100644 new mode 100755 index 8ca1eaf..41c7822 --- a/.env.test +++ b/.env.test @@ -1,3 +1,3 @@ DB_HOST="localhost" # cita config -CITA_URL="https://testnet.citahub.com" +CITA_URL="http://www.cita.com/" diff --git a/.env.test.local.travis b/.env.test.local.travis old mode 100644 new mode 100755 diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index a80e471..7948031 --- a/.gitignore +++ b/.gitignore @@ -9,9 +9,12 @@ # Ignore all logfiles and tempfiles. /log/* -/tmp/* !/log/.keep +/tmp/* !/tmp/.keep +!/tmp/pids/ +/tmp/pids/* +!/tmp/pids/.keep # Ignore uploaded files in development /storage/* @@ -45,3 +48,5 @@ docker/redis config/customs/*.yml db/migrate/*_create_customs_* app/models/customs/* +.DS_Store +TAGS diff --git a/.pryrc b/.pryrc old mode 100644 new mode 100755 diff --git a/.rspec b/.rspec old mode 100644 new mode 100755 diff --git a/.rubocop.yml b/.rubocop.yml old mode 100644 new mode 100755 diff --git a/.ruby-gemset.sample b/.ruby-gemset.sample old mode 100644 new mode 100755 diff --git a/.ruby-version b/.ruby-version old mode 100644 new mode 100755 diff --git a/.travis.yml b/.travis.yml old mode 100644 new mode 100755 index 2a40073..5073cca --- a/.travis.yml +++ b/.travis.yml @@ -35,8 +35,8 @@ before_script: - psql -c 'create database "re-birth_test";' -U postgres - cp .env.test.local.travis .env.test.local # run code quality audit - - gem install code_quality - - code_quality security_audit bundler_audit_options="--ignore CVE-2020-8164 CVE-2020-8166 CVE-2020-15169 CVE-2020-5267 CVE-2020-8167 CVE-2020-8162 CVE-2020-8165 CVE-2020-26247" + - gem install code_quality --no-ri --no-rdoc + - code_quality security_audit - code_quality quality_audit fail_fast=false generate_index=true skip_lowest_score=89 rubocop_max_offenses=400 script: diff --git a/.yardopts b/.yardopts old mode 100644 new mode 100755 diff --git a/API_DOC.md b/API_DOC.md deleted file mode 100644 index e8be08f..0000000 --- a/API_DOC.md +++ /dev/null @@ -1,407 +0,0 @@ -# API Doc - -### JSON-RPC Interface - -JSON-RPC interface, same format with [CITA JSON-RPC](http://docs.citahub.com/en-US/cita/rpc-guide/rpc). - -> POST / - -#### params - -```ruby -{ - "jsonrpc": "2.0", - "id": 83, - "method": "blockNumber", - "params": [] -} -``` - -#### response - -```ruby -{ - "jsonrpc": "2.0", - "id": 83, - "result": "0x7169a" -} -``` - -### System infos - -> GET /api/info/url - -Get the http and websocket url which ReBirth connected. - -#### response - -```ruby -{ - "result": { - "http_url": "http://localhost:1337", - "ws_url": "http://localhost:4337" - } -} -``` - -### Blocks - -Get blocks info list and paginate it. - -> GET /api/v2/blocks - -#### params - -Also Support camelCase. - -```ruby -{ - "block_number_from": "10" or "0xa", # number or integer - "block_number_to": "20", # number or integer - "min_transaction_count": "min transaction count", # integer - "max_transaction_count": "max transaction count", # integer - "page": "1", # default 1 - "per_page": "10", # default 10 - - # offset and limit has lower priority than page and perPage - "offset": "1", # database offset for pagination - "limit": "10", # database limit for pagination -} -``` - -#### response - -```ruby -{ - "result": { - "blocks": [ - { - "version": 0, - "header": { - "proof": { - "Bft": { - "round": 0, - "height": 111198, - "commits": { - "0x31042d4f7662cddf8ded5229db3c5e7302875e10": "0x8132cc5090329854a7dc22300b45c5d972f02a1e558e0b1fa71916316ad2fe061c06829b8b5eb16a7d206f421061a392cd6aad7a1d0a05a8c3e7203fe78a181e00", - "0x486bb688c8d29056bd7f87c26733048b0a6abda6": "0x4aa508798a0b9b77cc1263ae6b64d78977909fd2ce28e4f9322369041a3175cc4f7ad376b122c4b201dc6d2910c515f3d6d94c35dbd13fa6207a91fa8fd649b400", - "0x71b028e49c6f41aaa74932d703c707ecca6d732e": "0xc1e580fa36b0ae5740ca66b612df6d3435c29d20fa21292c93a8bacd7751eee87984a3720576dbad15527bd3a52c9cda42a2d58a382701ab835add5e11bbed1001" - }, - "proposal": "0xc880eb00df297b3c96bc08dca378280f99955816c6f32c08c17f004c0c7dfe75" - } - }, - "number": "0x1b25f", - "quotaUsed": "0x0", - "prevHash": "0x4bf32733fa6ca03326f0cfe7c487d7f8de26ad7c38fcf68959eebc2c0088e279", - "proposer": "0x31042d4f7662cddf8ded5229db3c5e7302875e10", - "stateRoot": "0x7e51d4969381493124b457e57db6dcab48c741a5046c327a43b59593d6a4ab16", - "timestamp": 1532648718735, - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - }, - "transactionsCount": 0, - "hash": "0x06208c3b241ff5b8a1fcdec9190abf0cc861d1e5ecdd4f696892fe7ee972473f" - } - ] - } -} -``` - -### Transactions - -Get transactions list and paginate it. - -> GET /api/v2/transactions - -#### params - -Also Support camelCase. - -```ruby -{ - "account": "the addr transactions related to (from or to)", # hash string - "from": "the addr transactions from", # hash string - "to": "the addr transactions to", # hash string - "value_format": "decimal", # set value to decimal number, default hex number - "page": "1", # integer, default 1 - "per_page": "10", # integer, default 10 - # offset and limit has lower priority than page and perPage - "offset": "1", # integer, default to 0 - "limit": "10", # integer, default to 10 -} -``` - -#### response - -```ruby -{ - "result": { - "count": 75178, - "transactions": [ - { - "value": "0x0000000000000000000000000000000000000000000000000000000000000000", # 0 if valueFormat=decimal - "to": "0xffffffffffffffffffffffffffffffffff010001", - "gasUsed": "0x45754", - "quotaUsed": "0x45754", - "from": "0x35f8ca15fdeb958d9ad60537bec5e35444dd6d93", - "content": "0x0ae70b0a286666666666666666666666666666666666666666666666666666666666666666666630313030303118c0843d20d480042a8e0bf2356b3877cb8fa08deb57a9ccf4f67e50012a2f5b7b22636f6e7374616e74223a747275652c22696e70757473223a5b7b226e616d65223a22222c2274797065223a2275696e74323536227d5d2c226e616d65223a22616c6c6f7765644d656d62657273222c226f757470757473223a5b7b226e616d65223a22222c2274797065223a2261646472657373227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e222c227369676e6174757265223a2230783164353563336631227d2c7b22636f6e7374616e74223a66616c73652c22696e70757473223a5b7b226e616d65223a2266696c65222c2274797065223a22737472696e67227d2c7b226e616d65223a2275726c73222c2274797065223a22737472696e67227d5d2c226e616d65223a2261646446696c65222c226f757470757473223a5b7b226e616d65223a2273756363657373222c2274797065223a22626f6f6c227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a226e6f6e70617961626c65222c2274797065223a2266756e6374696f6e222c227369676e6174757265223a2230783234386266633362227d2c7b22636f6e7374616e74223a747275652c22696e70757473223a5b7b226e616d65223a2266696c65222c2274797065223a22737472696e67227d5d2c226e616d65223a2267657446696c6555726c73222c226f757470757473223a5b7b226e616d65223a2275726c73222c2274797065223a22737472696e67227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e222c227369676e6174757265223a2230783831363234353763227d2c7b22636f6e7374616e74223a747275652c22696e70757473223a5b5d2c226e616d65223a226f776e6572222c226f757470757473223a5b7b226e616d65223a22222c2274797065223a2261646472657373227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e222c227369676e6174757265223a2230783864613563623562227d2c7b22636f6e7374616e74223a66616c73652c22696e70757473223a5b7b226e616d65223a2266696c65222c2274797065223a22737472696e67227d5d2c226e616d65223a2272656d6f766546696c65222c226f757470757473223a5b7b226e616d65223a2273756363657373222c2274797065223a22626f6f6c227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a226e6f6e70617961626c65222c2274797065223a2266756e6374696f6e222c227369676e6174757265223a2230786631616665303464227d2c7b22636f6e7374616e74223a747275652c22696e70757473223a5b7b226e616d65223a22222c2274797065223a2275696e74323536227d5d2c226e616d65223a2266696c6573222c226f757470757473223a5b7b226e616d65223a22222c2274797065223a2262797465733332227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e222c227369676e6174757265223a2230786634633731346234227d2c7b22696e70757473223a5b7b226e616d65223a225f616c6c6f7765644d656d62657273222c2274797065223a22616464726573735b5d227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a226e6f6e70617961626c65222c2274797065223a22636f6e7374727563746f72222c227369676e6174757265223a22636f6e7374727563746f72227d5d3220000000000000000000000000000000000000000000000000000000000000000038011241433a04695bfb3f3ada4266494093b80f317b8c795110fc2a223ad2c771377602c810ce591d7ae85695508eafe851ec080602c7fd7e2481bea43f0ece61189d6a01", - "blockNumber": "0xffff", - "hash": "0xf005a3585f9cfce03c7e428b9221eccdedeeae2736c8496c03113f90633135d8", - "timestamp": 1532511655997, - "chainId": 1, - "chainName": "test-chain", - "errorMessage": "Not enough base gas." - } - ] - } -} -``` - -### Transaction - -Get transactions info. - -> GET /api/transactions/:hash - -example -> GET /api/transactions/0x0000000000000000000000000000000000000000000000000000000000000000 - -#### params - -```ruby -{ - "account": "the addr transactions related to (from or to)", # hash string - "from": "the addr transactions from", # hash string - "to": "the addr transactions to", # hash string - "valueFormat": "decimal", # set value to decimal number, default hex number -} -``` - -#### response - -```ruby -{ - "result": { - "transaction": { - "value": "0x0000000000000000000000000000000000000000000000000000000000000000", # 0 if valueFormat=decimal - "to": "0xffffffffffffffffffffffffffffffffff010001", - "gasUsed": "0x45754", - "quotaUsed": "0x45754", - "from": "0x35f8ca15fdeb958d9ad60537bec5e35444dd6d93", - "content": "0x0ae70b0a286666666666666666666666666666666666666666666666666666666666666666666630313030303118c0843d20d480042a8e0bf2356b3877cb8fa08deb57a9ccf4f67e50012a2f5b7b22636f6e7374616e74223a747275652c22696e70757473223a5b7b226e616d65223a22222c2274797065223a2275696e74323536227d5d2c226e616d65223a22616c6c6f7765644d656d62657273222c226f757470757473223a5b7b226e616d65223a22222c2274797065223a2261646472657373227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e222c227369676e6174757265223a2230783164353563336631227d2c7b22636f6e7374616e74223a66616c73652c22696e70757473223a5b7b226e616d65223a2266696c65222c2274797065223a22737472696e67227d2c7b226e616d65223a2275726c73222c2274797065223a22737472696e67227d5d2c226e616d65223a2261646446696c65222c226f757470757473223a5b7b226e616d65223a2273756363657373222c2274797065223a22626f6f6c227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a226e6f6e70617961626c65222c2274797065223a2266756e6374696f6e222c227369676e6174757265223a2230783234386266633362227d2c7b22636f6e7374616e74223a747275652c22696e70757473223a5b7b226e616d65223a2266696c65222c2274797065223a22737472696e67227d5d2c226e616d65223a2267657446696c6555726c73222c226f757470757473223a5b7b226e616d65223a2275726c73222c2274797065223a22737472696e67227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e222c227369676e6174757265223a2230783831363234353763227d2c7b22636f6e7374616e74223a747275652c22696e70757473223a5b5d2c226e616d65223a226f776e6572222c226f757470757473223a5b7b226e616d65223a22222c2274797065223a2261646472657373227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e222c227369676e6174757265223a2230783864613563623562227d2c7b22636f6e7374616e74223a66616c73652c22696e70757473223a5b7b226e616d65223a2266696c65222c2274797065223a22737472696e67227d5d2c226e616d65223a2272656d6f766546696c65222c226f757470757473223a5b7b226e616d65223a2273756363657373222c2274797065223a22626f6f6c227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a226e6f6e70617961626c65222c2274797065223a2266756e6374696f6e222c227369676e6174757265223a2230786631616665303464227d2c7b22636f6e7374616e74223a747275652c22696e70757473223a5b7b226e616d65223a22222c2274797065223a2275696e74323536227d5d2c226e616d65223a2266696c6573222c226f757470757473223a5b7b226e616d65223a22222c2274797065223a2262797465733332227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e222c227369676e6174757265223a2230786634633731346234227d2c7b22696e70757473223a5b7b226e616d65223a225f616c6c6f7765644d656d62657273222c2274797065223a22616464726573735b5d227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a226e6f6e70617961626c65222c2274797065223a22636f6e7374727563746f72222c227369676e6174757265223a22636f6e7374727563746f72227d5d3220000000000000000000000000000000000000000000000000000000000000000038011241433a04695bfb3f3ada4266494093b80f317b8c795110fc2a223ad2c771377602c810ce591d7ae85695508eafe851ec080602c7fd7e2481bea43f0ece61189d6a01", - "blockNumber": "0xffff", - "hash": "0xf005a3585f9cfce03c7e428b9221eccdedeeae2736c8496c03113f90633135d8", - "timestamp": 1532511655997, - "chainId": 1, - "chainName": "test-chain", - "errorMessage": "Not enough base gas." - } - } -} - -# or not found -{ - "result": { - "transaction": null - } -} -``` - -### Statistics - -Get proposals info or brief info. - -> GET /api/statistics - -#### params - -```ruby -{ - type: "proposals" or "brief" # required -} -``` - -#### response - -```ruby -# when type = "proposals" -{ - "result": [ - { - "validator": "0x0000000000000000000000000000000000000000", # proposer of block header - "count": 1 # count of this proposer - }, - { - "validator": "0x31042d4f7662cddf8ded5229db3c5e7302875e10", - "count": 28514 - }, - { - "validator": "0x486bb688c8d29056bd7f87c26733048b0a6abda6", - "count": 27044 - }, - { - "validator": "0x71b028e49c6f41aaa74932d703c707ecca6d732e", - "count": 27844 - }, - { - "validator": "0xee01b9ba97671e8a1891e85b206b499f106822a1", - "count": 27797 - } - ] -} - -# when type = "brief" -{ - "result": { - "tps": 0, # float number, transaction count per second - "tpb": 0, # float number, transaction count per block - "ipb": 2.97 # float number, average block interval - } -} -``` - -### Status - -Get sync process running status. - -> GET /api/status - -#### response - -```ruby -{ - "result": { - "status": "not running", # sync process running status, "not running" or "running" - "currentBlockNumber": "0x1b25f", # last sync block - "currentChainBlockNumber": "0x717d0" # the chain current block number - } -} -``` - -### SyncErrors - -Get sync errors list, which is the errors while sync from chain. - -> GET /api/sync_errors - -#### params - -```ruby -{ - "page": 1, # integer, default 1 - "perPage": 10, # integer, default 10 - # offset and limit has lower priority than page and perPage - "offset": 1, # integer - "limit": 10, # integer -} -``` - -#### response - -```ruby -{ - "result": { - "count": 4, # total count of sync errors - "syncErrors": [ - { - "params": ["0x123"], # the params you send - "code": -32700, - "message": "invalid format: [0x123]", - "createdAt": "2018-08-07T03:21:15.862Z", - "updatedAt": "2018-08-07T03:21:15.862Z", - "data": null, - "method": "getTransaction" # the method you access - } - ] - } -} -``` - -### ERC20 Transfer event - -Get erc20 contracts transfer event logs by address - -> GET /api/erc20/transfers - -#### params - -```ruby -{ - "address": "0x...", # contract address, required - "account": "from or to", # hash - "from": "from address", # hash - "to": "to address", # hash - "page": 1, # default 1 - "perPage": 10, # default 10 - - # offset and limit has lower priority than page and perPage - "offset": 1, # default 0 - "limit": 10 # default 10 -} -``` - -#### response - -```ruby -{ - "result": { - "count": 1, - "transfers": [ - { - "address": "0x0b9a7bad10e78aefbe6d99e61c7ea2a23c3ec888", - "from": "0xac30bce77cf849d869aa37e39b983fa50767a2dd", - "to": "0x6005ed6b942c99533b896b95fe8a90c7a7ecbf6a", - "value": 10, - "blockNumber": "0x18a1ec", - "gasUsed": "0x64", - "quotaUsed": "0x64", - "hash": "0x14b06be4067ba65d05e41d8821e2cf7d572a65b1bf53857a6a504ec42e69fdfd", - "chainId": 1, - "chainName": "test-chain" - } - ] - } -} -``` - -### EventLog by address - -Get event logs by address - -> GET /api/event_logs/:address - -#### params - -```ruby -{ - "page": 1, # default 1 - "perPage": 10, # default 10 -} -``` - -#### response - -```ruby -{ - "result": { - "count": 1, - "eventLogs": [ - { - "address": "0x0b9a7bad10e78aefbe6d99e61c7ea2a23c3ec888", - "data": "0x000000000000000000000000000000000000000000000000000000000000000a", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x000000000000000000000000ac30bce77cf849d869aa37e39b983fa50767a2dd", - "0x0000000000000000000000006005ed6b942c99533b896b95fe8a90c7a7ecbf6a" - ], - "blockHash": "0xa2574fbd6fe9083ad8a1729630d1fa2c227f0a6df2dbb1f0d6d69faa4145c5cb", - "blockNumber": "0x18a1ec", - "logIndex": "0x0", - "transactionHash": "0x14b06be4067ba65d05e41d8821e2cf7d572a65b1bf53857a6a504ec42e69fdfd", - "transactionIndex": "0x0", - "transactionLogIndex": "0x0" - } - ] - } -} -``` diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 8cb0304..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,277 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - -## [v0.4.0](https://github.com/citahub/re-birth/releases/tag/v0.4.0) ([compare](https://github.com/citahub/re-birth/compare/v0.3.0...v0.4.0)) - -### Added -- Add /api/v2/transactions ([32104c4](https://github.com/citahub/re-birth/commit/32104c4a60086ed1b8e08b3e86a234fb8c34021f) by classicalliu). - -### Fixed -- Fix typo ([a20574e](https://github.com/citahub/re-birth/commit/a20574efe1c5c2796a5952d9159af5b8d9817337) by CL). -- Fix: fix /api/v2/blocks in api doc ([99ec6d8](https://github.com/citahub/re-birth/commit/99ec6d803af928bf8807e02a9320770890072bce) by classicalliu). - -### Misc -- Upgrade sdk for v0.24.0 v2 support ([f955b20](https://github.com/citahub/re-birth/commit/f955b20af4b90ed1d1125a5d729fa305b877e9f7) by classicalliu). -- Disable recover mode and only support v0.22 and above ([6cec7ca](https://github.com/citahub/re-birth/commit/6cec7ca8a2bce194a131df2d8f979fc6f14bda8b) by classicalliu). -- Better expression ([37758f9](https://github.com/citahub/re-birth/commit/37758f9e237bfe8edd0730295e9235e205d7db37) by CL). -- Error: in file ./.env: environment variable name 'loop_interval ' may not contains whitespace. ([c116b3b](https://github.com/citahub/re-birth/commit/c116b3bd0afc9b7a3a9dc8e77f7af6951c04bd86) by sunfjun). - - -## [v0.3.0](https://github.com/citahub/re-birth/releases/tag/v0.3.0) ([compare](https://github.com/citahub/re-birth/compare/0.2.0...v0.3.0)) - 2019-04-25 - -### Added -- Add /v2/api/blocks ([c62ad8f](https://github.com/citahub/re-birth/commit/c62ad8f48968ffbf2fce91fd0d1786a5b692d8e3) by classicalliu). -- Add chinese version of readme ([f2176d0](https://github.com/citahub/re-birth/commit/f2176d00514a7f47c0ddae0236fd0efb54c99d59) by classicalliu). -- Add api for cita rpc url and websocket url info ([d9687da](https://github.com/citahub/re-birth/commit/d9687da81f0f98eba9adbeb1ea9c928060fc36ae) by classicalliu). -- Add `timestamp`, `quota_used`, `proposer` to blocks and add `timestamp` to transactions ([02e1b38](https://github.com/citahub/re-birth/commit/02e1b38d4bac49b00779f746c55ed607cce7d9df) by classicalliu). -- Add sidekiq auth for production env. ([1d43716](https://github.com/citahub/re-birth/commit/1d43716153e06856d10200739faffce843c5fc25) by classicalliu). -- Add sidekiq and redis to docker compose. ([1dd129e](https://github.com/citahub/re-birth/commit/1dd129e11ffca4bec40ed43210c14e2c0415af7c) by classicalliu). -- Add root url info to instead of not found ([d57425b](https://github.com/citahub/re-birth/commit/d57425b20ade1e89d93c0092d823fbf6e570fe6b) by classicalliu). -- Add timestamp in erc20 transfers ([1d7aec5](https://github.com/citahub/re-birth/commit/1d7aec5e04643b797173d29ead340e5586d37ffa) by classicalliu). -- Add readme: add event log show api ([b703cc6](https://github.com/citahub/re-birth/commit/b703cc6d98766b4c4a16d398f24eb17aa0f514aa) by classicalliu). -- Add event log show api ([97eea5c](https://github.com/citahub/re-birth/commit/97eea5c2a709536c14a085fae88e4ae046e1fc12) by classicalliu). -- Add errormessage to transactions ([02b3cc6](https://github.com/citahub/re-birth/commit/02b3cc68619d36d90a186805659add2da3f0267b) by classicalliu). - -### Changed -- Change loop interval ([78da98f](https://github.com/citahub/re-birth/commit/78da98fa6949777cea979e59933bc024fe53dc96) by classicalliu). -- Change `block_number`, `value`, `quota_used` and so on to decimal number ([d8cb2e4](https://github.com/citahub/re-birth/commit/d8cb2e4c23e37278ddb7316b32dafc3bced641a9) by classicalliu). -- Change blocks, transactions, event_logs, erc20_transfers pkey and fkey. ([3927b03](https://github.com/citahub/re-birth/commit/3927b03487fb7acc5f2b42262d74a93d243d44a6) by classicalliu). - -### Fixed -- Fix docker-compose log file not found problem ([e43a94c](https://github.com/citahub/re-birth/commit/e43a94c61d5d62d0c9b17586991cc41cee93f537) by classicalliu). -- Fix sync log not write problem add fix sync interval ([7e78153](https://github.com/citahub/re-birth/commit/7e78153136370ee869e1bade03e82a7cdbaa26e5) by classicalliu). -- Fix `tx.event_logs` and `tx.erc20_transfers` null problem ([7ecf510](https://github.com/citahub/re-birth/commit/7ecf510858d0b0c5e7095e681fa16b10aa2fbf0b) by classicalliu). -- Fix ws url scheme ([0b1ad09](https://github.com/citahub/re-birth/commit/0b1ad0972986bee7dfa75f7ce0fb9dd9e8260aa1) by classicalliu). -- Fix tests for `save_transaction` params ([3a2eb9d](https://github.com/citahub/re-birth/commit/3a2eb9df8dac07172f52b6167aaaeb64036aad98) by classicalliu). -- Fix for old name `cita_hash` ([d2c9d13](https://github.com/citahub/re-birth/commit/d2c9d1365b4b8c4566301615519ff974ebf80ebe) by classicalliu). -- Fix bug: erc20_transfers persist ([47f2330](https://github.com/citahub/re-birth/commit/47f2330e341562ba786a5028931a50eb91395c0e) by classicalliu). - -### Removed -- Remove useless balance and abi ([e41229b](https://github.com/citahub/re-birth/commit/e41229bcde2748688f1a6781a41b4fc6e2a3ea89) by classicalliu). -- Remove include block from transaction controller ([92fe6a2](https://github.com/citahub/re-birth/commit/92fe6a2738f4830bf8d925f21dbfb4bf87217021) by classicalliu). -- Remove get transaction rpc call when save transaction ([947ef3b](https://github.com/citahub/re-birth/commit/947ef3bf2c6893ae5b5fb2f639e410f7beb50279) by classicalliu). -- Remove error scope in transaction receipt ([e6826d2](https://github.com/citahub/re-birth/commit/e6826d2bc844ded482d2de25c093c7a122bdd356) by classicalliu). - -### Misc -- Format api doc ([fc990c8](https://github.com/citahub/re-birth/commit/fc990c8cbe7da0ec567b99f8e066d1d0bdafcec0) by classicalliu). -- Rename /v2/blocks params ([f1feb43](https://github.com/citahub/re-birth/commit/f1feb43d58c3f84c7007ceed94b74f2dda1e6e76) by classicalliu). -- Transform v2/blocks keys ([d8f90c3](https://github.com/citahub/re-birth/commit/d8f90c3e4a5de9e92628bcaea04bd0952cebf39c) by classicalliu). -- Update nokogiri ([6546369](https://github.com/citahub/re-birth/commit/654636964fc4f02c7f40182ee25644004809ccbc) by classicalliu). -- Update rails to fix security problem ([f7a302c](https://github.com/citahub/re-birth/commit/f7a302cc5741dd04f6fbc2afadc85e73b219c102) by classicalliu). -- Split api doc to a single file ([fbfdb73](https://github.com/citahub/re-birth/commit/fbfdb737196a18f64bb04f4b08d469c83d21cccf) by classicalliu). -- Replace cita doc url ([be88c07](https://github.com/citahub/re-birth/commit/be88c07e7813d6c6f60068be3268d51a00b13a11) by classicalliu). -- Replace `appchain.rb` with `cita-sdk-ruby` ([711fc5c](https://github.com/citahub/re-birth/commit/711fc5c1f638eadb4e3da33a3b4910779955d81f) by classicalliu). -- Update erc20 transfer api doc ([d39afc5](https://github.com/citahub/re-birth/commit/d39afc5ab83e17e85a2b69c7b400a46cc6c93a97) by classicalliu). -- Lock appchain.rb version to 0.2.0 ([f92ff26](https://github.com/citahub/re-birth/commit/f92ff260a8d0e3fd085e7e5827d4a1cfa0a600ef) by classicalliu). -- Rename `infos` to `info` ([ec42a11](https://github.com/citahub/re-birth/commit/ec42a111c1aff74f3e3cb25a8a06cd31d1eb9e1d) by classicalliu). -- Update rails version to 5.2.2 ([dfe0f83](https://github.com/citahub/re-birth/commit/dfe0f8324638e7712c3e2cf5b1c3ff3bfb57c682) by classicalliu). -- Rjust tx value to size 64 ([30fc089](https://github.com/citahub/re-birth/commit/30fc0890c64601dca0ce7ab4153a90abb76473e6) by classicalliu). -- Update controllers and serializers for changed pkey ([419edd2](https://github.com/citahub/re-birth/commit/419edd28994c32eab72200760a242c2fcb909929) by classicalliu). -- Using `push_bulk` to push a list of workers, it performs better ([aa9b119](https://github.com/citahub/re-birth/commit/aa9b11973c076475b58cf0e36a3def139d31deac) by classicalliu). -- Return error object when rpc error in tx ([5e59ab4](https://github.com/citahub/re-birth/commit/5e59ab4c11cf806fa7f97c197819dc0640eec1d2) by classicalliu). -- Save tx and it's event logs in one db transaction ([179305b](https://github.com/citahub/re-birth/commit/179305b6571d3c035d67cf24c44a5726bb8c404a) by classicalliu). -- Retry when save tx or event logs failed ([3722786](https://github.com/citahub/re-birth/commit/3722786677700d71f57d423a3b630aaa516434f2) by classicalliu). -- Skip check queue size in test ([e5e97fa](https://github.com/citahub/re-birth/commit/e5e97fa19505026eae1ad2c4ba5286c7479a9156) by classicalliu). -- Insert block in sidekiq and handle system timeout and not ready error ([3e6e43b](https://github.com/citahub/re-birth/commit/3e6e43b6aae75a90adee8477e0d2330fad7bc40d) by classicalliu). -- Don't enable experimental for secp256k1, create pids dir before start docker. ([1f6b911](https://github.com/citahub/re-birth/commit/1f6b9116cf045a2bf58f949332785cfb728caac4) by classicalliu). -- Update rails to 5.2.1.1 for security. ([bdedfa7](https://github.com/citahub/re-birth/commit/bdedfa7db0329a45dbf17a6a28ddfec88bdaac4f) by classicalliu). -- Update readme for fix a display issue. ([7b67e53](https://github.com/citahub/re-birth/commit/7b67e5387afc9b78d305a4a9ae6ef1f303aa4a77) by classicalliu). -- Set default redis namespace to nil. ([309ff73](https://github.com/citahub/re-birth/commit/309ff73db1d92da71fa2f04005708a48508d6e25) by classicalliu). -- Update readme for sidekiq and redis infos. ([b6dd3fd](https://github.com/citahub/re-birth/commit/b6dd3fde195f2e0233cdf84d169dbeb349ca3ce0) by classicalliu). -- Reset sidekiq pid path in deploy script. ([be77127](https://github.com/citahub/re-birth/commit/be771274e564258924b6d94df438f24fcf6a1ea8) by classicalliu). -- Using sidekiq to process transactions and event logs. ([7c80caf](https://github.com/citahub/re-birth/commit/7c80cafe5877b4c6bce769cfc3be9fe20c92e015) by classicalliu). -- Using appchain.rb to make rpc calls and replace message decode ([0066a2b](https://github.com/citahub/re-birth/commit/0066a2be357286275fbc53d798fa9200188c0bf0) by classicalliu). -- Update docker ruby version. ([eab20cb](https://github.com/citahub/re-birth/commit/eab20cb9ca8802a82e1742f9baecdd76e9d6a1d2) by classicalliu). -- Update deploy script ruby version. ([744e546](https://github.com/citahub/re-birth/commit/744e54617bc6e8bb0ac9a6cbd21d42a32ad04d15) by classicalliu). -- Update ruby version to 2.5.3 and update gems. ([2a6e033](https://github.com/citahub/re-birth/commit/2a6e033bcbb7d086357e7b833db87beb49441dfa) by classicalliu). -- Update readme for 0.20 changes ([9817876](https://github.com/citahub/re-birth/commit/9817876362435ecc393efdeab71228b4348becf1) by classicalliu). -- Rename gas_used to quota_used ([727bcd3](https://github.com/citahub/re-birth/commit/727bcd3e1734ce59cb7c813c1e67d3f184cc34e5) by classicalliu). -- Update serializer chain_id ([f549b8b](https://github.com/citahub/re-birth/commit/f549b8b04978f26c671bd892be9ae2a25b384e23) by classicalliu). -- Update `loofah` version to 2.2.3 for security ([d5506e4](https://github.com/citahub/re-birth/commit/d5506e4903decbc26a5e8c6eede65c806e1049d1) by classicalliu). -- Support cita 0.20 forks (version 0 & version 1) ([628500b](https://github.com/citahub/re-birth/commit/628500b65faee8316f7c56a863a4ef5706555158) by classicalliu). -- Update homepage message ([a4dcdd5](https://github.com/citahub/re-birth/commit/a4dcdd509056e56724a1880dca29208765324610) by James Chen). -- Move cors config from application.rb to initializers(rails api only standard) ([1305f11](https://github.com/citahub/re-birth/commit/1305f114f0dd5c75ae454f4590600bbf2f90ed7a) by classicalliu). -- Custom to api only structure ([6bccd51](https://github.com/citahub/re-birth/commit/6bccd511ebaba746332c1506834e245e95c487c4) by classicalliu). -- Set max_per_page to 100 ([96a2386](https://github.com/citahub/re-birth/commit/96a2386aae373a95eda032b5bca3f53fff6f509c) by classicalliu). -- Update readme: errormessage in api ([e69ec83](https://github.com/citahub/re-birth/commit/e69ec836c84d4ce8cf0d133f4fd24f074ce143e0) by classicalliu). -- Update readme: add error messages ([9145469](https://github.com/citahub/re-birth/commit/9145469d7fd1a7a18a23b4e611110e81be6d65a1) by classicalliu). -- Upgrade gem: nokogiri ([00fbbba](https://github.com/citahub/re-birth/commit/00fbbba36e1ae0edb993b0afac26426ec969d3ee) by classicalliu). -- Update ci: delete branch limit ([de6fdfb](https://github.com/citahub/re-birth/commit/de6fdfb3b4b1ee233ac1e5cc5903c6472804898f) by classicalliu). - - -## [0.2.0](https://github.com/citahub/re-birth/releases/tag/0.2.0) ([compare](https://github.com/citahub/re-birth/compare/v0.1.1...0.2.0)) - 2018-09-27 - -### Added -- Add rubocop and fix ([05a7a54](https://github.com/citahub/re-birth/commit/05a7a542fff9e4a8bf56ec518b24c6d6a602c070) by classicalliu). -- Add an api: find transaction with hash ([d58999e](https://github.com/citahub/re-birth/commit/d58999e1865809bc2647a0b5828682fbd292b0c5) by classicalliu). -- Add chainid and chainname to transaction and transfer list ([8c6c65e](https://github.com/citahub/re-birth/commit/8c6c65e930004ce0530526b85fca648303a388aa) by classicalliu). -- Add erc20 event log process ([be5e744](https://github.com/citahub/re-birth/commit/be5e744ff2931072af0360258f65d0d607754651) by classicalliu). -- Add block & transaction reference to event logs ([92563f8](https://github.com/citahub/re-birth/commit/92563f86254c71b7ccf447fe85e02ce1cc08c418) by classicalliu). -- Add event logs, sync event logs while sync transactions ([2f1de8c](https://github.com/citahub/re-birth/commit/2f1de8c109dbbd9446ea1130395df1fe44bb4501) by classicalliu). -- Add healthy check ([67b1259](https://github.com/citahub/re-birth/commit/67b1259ea9751da4dfd2cb466d25355177f93a35) by classicalliu). -- Add release branch to ci ([50e0d52](https://github.com/citahub/re-birth/commit/50e0d52f9d86cce2a173cb1ff28dcabfc98ebb71) by classicalliu). -- Add staging and production deploy script ([3eb295d](https://github.com/citahub/re-birth/commit/3eb295d9c5ff753b0da1ef70603c42e8be230bfd) by classicalliu). - -### Documented -- Docker support 🐳 ([522afce](https://github.com/citahub/re-birth/commit/522afceb0f8873222481d605bb50a843dbf7f84a) by classicalliu). - -### Fixed -- Fix: raise error when result is nil in fix_old task ([4e94730](https://github.com/citahub/re-birth/commit/4e94730d1d16f69fd3060c622ae60e6719c382e4) by classicalliu). -- Fix brakeman bug ([3b5b1e9](https://github.com/citahub/re-birth/commit/3b5b1e98f05be67972a35e5d0456774ce7101ec6) by classicalliu). -- Fix factorybot/attributedefinedstatically ([aa9ec02](https://github.com/citahub/re-birth/commit/aa9ec021bb32d4cb7e9998da3a40d4a985d2ce89) by classicalliu). -- Fix two `before_script` problem in ci config ([21f96a3](https://github.com/citahub/re-birth/commit/21f96a34d5dc97d8edb3e099bde562aa853bd162) by classicalliu). -- Fix message_spec ([eaf6bb7](https://github.com/citahub/re-birth/commit/eaf6bb7c77c11a4aab0dcea25e82302bee9dc9b5) by classicalliu). -- Fix proposals order, may strange in microscope... ([3399d2e](https://github.com/citahub/re-birth/commit/3399d2ea0eb98cacc7b57f5f3b65d757d13bf0e2) by classicalliu). -- Fix typo: tendermint => tendermint ([72dfac6](https://github.com/citahub/re-birth/commit/72dfac6ef5d6f031434e14eb0f4c0027f99718fc) by classicalliu). -- Fix upgrade to cita v0.18 migration, drop old and create new one, for work with pg v9.4 ([932a2aa](https://github.com/citahub/re-birth/commit/932a2aa468c4df751e328ae8f54e9ef60ce77990) by classicalliu). -- Fix test db host ([64cbcce](https://github.com/citahub/re-birth/commit/64cbcce1852ab44cfaf676d3c0aa53198031362d) by classicalliu). - -### Removed -- Remove event log (no use anymore...) ([f161f8a](https://github.com/citahub/re-birth/commit/f161f8aefa8849e36dacbaafde2e920bcd9c3416) by classicalliu). -- Remove migration and model files for event logs... ([446f072](https://github.com/citahub/re-birth/commit/446f0729fb4d9f03b53cc88a7714a9a725a46f6e) by classicalliu). -- Remove metadata, it's no need to save. ([d957f78](https://github.com/citahub/re-birth/commit/d957f78e22547648554dedd21e8f52e3c865f516) by classicalliu). - -### Misc -- Delete unused (commented out) gems ([95ebf50](https://github.com/citahub/re-birth/commit/95ebf50eee11e763150a41b670d59f7258dbc32f) by James Chen). -- Specify rubocop version ([3380c2e](https://github.com/citahub/re-birth/commit/3380c2eda48cd4d4f473dccb1fed4a74a5c6f1f8) by James Chen). -- Bug fix: select event logs ignore case when process erc20 transfers ([ce36476](https://github.com/citahub/re-birth/commit/ce364769b673133afb25f07b97a1e64925a9ed01) by classicalliu). -- Save erc20 transfer address in lower case ([1793fc3](https://github.com/citahub/re-birth/commit/1793fc30fc27b63fe558175e2ce0c2ce277888b3) by classicalliu). -- Update comment for before_script in .travis.yml ([17b6775](https://github.com/citahub/re-birth/commit/17b6775c03fc41146696b1ec05d918e74d8e1cff) by RainChen). -- Set default cita_url to localhost ([ee9a505](https://github.com/citahub/re-birth/commit/ee9a505ae6babb5f5fbe365a3ff2f6634cfbd04a) by classicalliu). -- Update readme for update note ([50d5e9b](https://github.com/citahub/re-birth/commit/50d5e9bc86d78a7f22dd05ac72915a774b8f24f9) by classicalliu). -- Update gems and fix it's problems ([e4c76fc](https://github.com/citahub/re-birth/commit/e4c76fcba11b10df956ca943d53c0a7cce127201) by classicalliu). -- Update readme for erc20 transfers ([181d2f3](https://github.com/citahub/re-birth/commit/181d2f3722ac1ff9faecf4b33db81f3018dde678) by classicalliu). -- Auto run code quality audit task on ci ([704b027](https://github.com/citahub/re-birth/commit/704b02780b332593ef8f13efd08c932eceae29f6) by RainChen). -- Set valueformat=decimal in transaction list ([d2c3d61](https://github.com/citahub/re-birth/commit/d2c3d61a3709f7c705c8ee1e84b8ab58c7495849) by classicalliu). -- Set root get path to 404 no found ([dd5d59f](https://github.com/citahub/re-birth/commit/dd5d59fe8de15a6a43a3a166ea1f1c3239bab9c8) by classicalliu). -- Update readme, add event log processor info ([3e7a155](https://github.com/citahub/re-birth/commit/3e7a1550fc3a68036ed00314c684eb04bf3c79f0) by classicalliu). -- Move upgrade 0.18 script from migration to rake task and note that in readme ([9d87f48](https://github.com/citahub/re-birth/commit/9d87f487381e6739fdb05eef8441d95aee7f901d) by classicalliu). -- Test event log processor ([3cad25b](https://github.com/citahub/re-birth/commit/3cad25bb65629923f7f0b8aa02001ae7f04f6da1) by classicalliu). -- Rename eventlogprocess to eventlogprocessor ([638246b](https://github.com/citahub/re-birth/commit/638246b02bd6036665acb55a7445f28ccf638731) by classicalliu). -- Cache validator counter ([91efc85](https://github.com/citahub/re-birth/commit/91efc8541bf6159d2e06bfd1108faa759f792b7c) by classicalliu). -- Create a contract event log by custom config ([879b492](https://github.com/citahub/re-birth/commit/879b49241491bd58398a45f3dab1c9897fac9d16) by classicalliu). -- Update readme ([0c4c914](https://github.com/citahub/re-birth/commit/0c4c91485fcb4a18d0af16a89d217aa46e64836a) by classicalliu). -- Ignore from and to case when get transactions ([1c794f6](https://github.com/citahub/re-birth/commit/1c794f6fad9a6a555a3f7a15d650a85c9fbc72c8) by classicalliu). -- Upgrade to work with cita v0.18 ([35b64da](https://github.com/citahub/re-birth/commit/35b64dab58cc3b6ee8951701d7b12ba512bb5ec0) by classicalliu). -- Replace appchain with appchain ([2c9d297](https://github.com/citahub/re-birth/commit/2c9d2975065d3f7db582e0620c6e47a919cdc5b3) by classicalliu). -- Update readme for db data path ([ca6fce6](https://github.com/citahub/re-birth/commit/ca6fce67cb9741ff68c7aa18296c054a7e8103a3) by classicalliu). -- Set docker app lang ([2b45e80](https://github.com/citahub/re-birth/commit/2b45e80beef42df91603c83182e14882c7f2bec0) by classicalliu). -- Replace credentials with secrets... ([4007801](https://github.com/citahub/re-birth/commit/40078016255d61b89f60ffaaddeeebd746b1504a) by classicalliu). -- Optional blocks ([b169240](https://github.com/citahub/re-birth/commit/b16924054f2f6eb3bb49f39c86a39d46a850d21e) by classicalliu). -- Update proposals algorithm ([cd190f0](https://github.com/citahub/re-birth/commit/cd190f0c59cd7c893e087b98a4f99a210f736525) by classicalliu). - - -## [v0.1.1](https://github.com/citahub/re-birth/releases/tag/v0.1.1) ([compare](https://github.com/citahub/re-birth/compare/v0.1.0...v0.1.1)) - 2018-08-16 - -### Added -- Add index to block header and body ([d4b0f08](https://github.com/citahub/re-birth/commit/d4b0f08dd99dbe12c37462111364d7fe9f11a5b2) by classicalliu). - -### Fixed -- Fix pagination problem, be with only offset or limit provided ([7fd6310](https://github.com/citahub/re-birth/commit/7fd6310c771d09853ec15c5fe1662c6dece922bb) by classicalliu). -- Fix a bug: tendermint => tendermint ([dd8aa12](https://github.com/citahub/re-birth/commit/dd8aa1281eb7a58e1e135266e601552eef500d34) by classicalliu). - -### Misc -- Proposals get validators from metadata ([339b821](https://github.com/citahub/re-birth/commit/339b821b08c494b1ee237acd7956131c922022c9) by classicalliu). -- Resort transactions in controller ([3e45a80](https://github.com/citahub/re-birth/commit/3e45a8046835b6188d1915cd9c4769297d80b215) by classicalliu). - - -## [v0.1.0](https://github.com/citahub/re-birth/releases/tag/v0.1.0) ([compare](https://github.com/citahub/re-birth/compare/1dc8f65bc320235c3230e53bf528bac309b5d992...v0.1.0)) - 2018-08-13 - -### Added -- Add yard doc icon to readme ([8d40dde](https://github.com/citahub/re-birth/commit/8d40ddeff52dd93de5fd83787fd3aa62dce81f2b) by classicalliu). -- Add not found handle ([bb019b7](https://github.com/citahub/re-birth/commit/bb019b7bee149a3e690a94ed850f8a1027bfb503) by classicalliu). -- Add data to sync errors ([c4ea95c](https://github.com/citahub/re-birth/commit/c4ea95c8170d6128c9c52a81dd1f5a73df3fcbd0) by classicalliu). -- Add sync errors controller ([f25d2b1](https://github.com/citahub/re-birth/commit/f25d2b14d7f320a8ba42ed94c4ed059d4fdf12f6) by classicalliu). -- Add sync error records ([972f530](https://github.com/citahub/re-birth/commit/972f53094cb17f9658a52393845f6e75d06f479a) by classicalliu). -- Add hex utils ([9b9ea8d](https://github.com/citahub/re-birth/commit/9b9ea8d9284e0c1fccd7b721a77402c4e08ea4f7) by classicalliu). -- Add status controller ([6ed8dec](https://github.com/citahub/re-birth/commit/6ed8dec1f5d92de4a64191db9fb3cc8dbac16ab8) by classicalliu). -- Add deploy script ([7ed11a5](https://github.com/citahub/re-birth/commit/7ed11a5a9d76c008301b53a5bca00104c5c74a0a) by classicalliu). -- Add cita sync module test ([eaa9724](https://github.com/citahub/re-birth/commit/eaa97240cb8835b25c795e279f116f5d4c57c7f9) by classicalliu). -- Add some comments ([b7a2097](https://github.com/citahub/re-birth/commit/b7a209792bfe729d28927ac3680ab2f1c3b26503) by classicalliu). -- Add comments to api and basic class ([7690b0b](https://github.com/citahub/re-birth/commit/7690b0bc4d43cea681fac82c725bb979a67cfcbb) by classicalliu). -- Add comments to message class ([826db33](https://github.com/citahub/re-birth/commit/826db335bf690080ad88da87cdc1598afd73386f) by classicalliu). -- Add yard for doc ([e7b3d83](https://github.com/citahub/re-birth/commit/e7b3d8336b05f88091ff49f137a8cfa1324bb7c3) by classicalliu). -- Add codecov icon ([50a3623](https://github.com/citahub/re-birth/commit/50a36234ee7d9461095bf4c989e42d366725c1cf) by classicalliu). -- Add codecov ([c0e44b2](https://github.com/citahub/re-birth/commit/c0e44b2f598325644983af48b20d27f6a838de17) by classicalliu). -- Add rspec test suites ([12de9f2](https://github.com/citahub/re-birth/commit/12de9f2d999e732c45a397a50c0fa851bbedcf8d) by classicalliu). -- Add statistics api ([87577d8](https://github.com/citahub/re-birth/commit/87577d8b2ceb53e3363d25a1374d8be0a374e01f) by classicalliu). -- Add transaction controller and add index action ([3ca6fc7](https://github.com/citahub/re-birth/commit/3ca6fc720e1458cec424522bcd73d941597c73bb) by classicalliu). -- Add offset and limit support to controller index action ([ad04b1c](https://github.com/citahub/re-birth/commit/ad04b1c6d73358c3254a75e3f489997103f41b56) by classicalliu). -- Add getblockbyhash to localinfocontroller ([bdc2d8e](https://github.com/citahub/re-birth/commit/bdc2d8e3529cccf513446157f73caa3e32518b1d) by classicalliu). -- Add more useful columns to transaction ([3f027ae](https://github.com/citahub/re-birth/commit/3f027aeb69b67c096cc1801f832f2e48c249f445) by classicalliu). -- Add message model to process transaction content and get original value ([4bcd15f](https://github.com/citahub/re-birth/commit/4bcd15fb5c87e7d0c956dc133d7a6f4deb542320) by classicalliu). -- Add transaction_count to block and add blocks controller ([f1f1b00](https://github.com/citahub/re-birth/commit/f1f1b008e66d335aaacf3e58dcd9eba0b2a566a3) by classicalliu). -- Add travis ci build status to readme ([0c8b25a](https://github.com/citahub/re-birth/commit/0c8b25aff0971127d1162a6481811c3ccc317dff) by classicalliu). -- Add cita api ([d5c9667](https://github.com/citahub/re-birth/commit/d5c96674e6d0d439dfee9a8e71d57034b99ddb9e) by classicalliu). -- Add abi model ([eb47751](https://github.com/citahub/re-birth/commit/eb477516794182d57018551b5c0e51edce75278d) by classicalliu). -- Add travis ci files ([66919c0](https://github.com/citahub/re-birth/commit/66919c0dc643d859443530a93196a8e1f86c0651) by classicalliu). -- Add balance model and fix a test bug ([8242e3f](https://github.com/citahub/re-birth/commit/8242e3fa8b237d74a3d28bd2d85bba97ac2ddb7d) by classicalliu). -- Add meta data model and persisted it ([30674d4](https://github.com/citahub/re-birth/commit/30674d459d346b700f589ed0c859745eb84d6284) by classicalliu). -- Add license ([03aa854](https://github.com/citahub/re-birth/commit/03aa8542092f8865ef99ae679a03ecaff448877f) by classicalliu). -- Add block and transaction model and sync them ([e3d2d31](https://github.com/citahub/re-birth/commit/e3d2d3121fb4994203430b4284dbf90c293a2734) by classicalliu). -- Add pry for console and awesome print ([975fc7b](https://github.com/citahub/re-birth/commit/975fc7b482c04f49674c44ed186fbd7155ab3fc3) by classicalliu). - -### Changed -- Change nervos appchain link ([0bc3c4c](https://github.com/citahub/re-birth/commit/0bc3c4c477ff81e14ea9ac35e9ce69234a560834) by Mine77). - -### Fixed -- Fix concern yard doc problem ([406280d](https://github.com/citahub/re-birth/commit/406280d62002f90edec629f2cadf8842f4cf92f6) by classicalliu). -- Fix license ([58a9739](https://github.com/citahub/re-birth/commit/58a9739d99bc8d64a354d554a254fbd3d82de430) by classicalliu). -- Fix ci ([2aa93cf](https://github.com/citahub/re-birth/commit/2aa93cf8c92417c010f1ae6f0925229a6d61d988) by classicalliu). -- Fix a bug ([e609c6e](https://github.com/citahub/re-birth/commit/e609c6ef330ec4fb9fdbe8121e9d79ab80dbd6b6) by classicalliu). -- Fix travis ci ([4c871f1](https://github.com/citahub/re-birth/commit/4c871f1776a820731505c1e929a81d471e904bcd) by classicalliu). - -### Removed -- Remove test dir ([45a20cd](https://github.com/citahub/re-birth/commit/45a20cd2999ed0a4976a159393603ec949227984) by classicalliu). - -### Misc -- Rename rebirth to re-birth ([9dbbdfb](https://github.com/citahub/re-birth/commit/9dbbdfb2535f6c5502b3d1b338a015e9287a366c) by classicalliu). -- Update readme.md (#5) ([2ba4f50](https://github.com/citahub/re-birth/commit/2ba4f509dac29c39ceef30c9f26a286935a13aef) by Mine77). -- Update readme for env set ([75dd4d6](https://github.com/citahub/re-birth/commit/75dd4d60cb64c203d7f47fc9e6f21b400c03c6d5) by classicalliu). -- Update: add bundle step to doc ([5432ff2](https://github.com/citahub/re-birth/commit/5432ff2eca46a1f187476afd7c1e0e911dafc781) by Keith). -- Update readme for secp256k1 install info ([41d1ca7](https://github.com/citahub/re-birth/commit/41d1ca720b8402a836ff554fb4629c063e331f1a) by classicalliu). -- Update readme for deploy and apidocs ([0f37829](https://github.com/citahub/re-birth/commit/0f378295a8180d47a2ded8db1ea01651ab4289ae) by classicalliu). -- Update persist comments ([2a17c4a](https://github.com/citahub/re-birth/commit/2a17c4a123c705b89f5ff49c232e3b5bc4e4edf1) by classicalliu). -- Make save_balance and save_abi return format concord ([590a223](https://github.com/citahub/re-birth/commit/590a2236f8a8e8fdd524a38b55e3b19b1504decd) by classicalliu). -- Rename basic to http and remove useless methods ([ceca7b4](https://github.com/citahub/re-birth/commit/ceca7b46296fc7640be98ca69a70265a7801860a) by classicalliu). -- Move local infos and split requests controllers to concerns ([d1692a4](https://github.com/citahub/re-birth/commit/d1692a48d159c09039a1aa138feb2925cb825aee) by classicalliu). -- Update codecov icon ([1ddd0f8](https://github.com/citahub/re-birth/commit/1ddd0f8096550d51bba6178d3264acd606e99ac0) by classicalliu). -- Update travis ci to support codecov ([fe37f00](https://github.com/citahub/re-birth/commit/fe37f00a7a7c46ea7f3df170330099b9b6a59737) by classicalliu). -- Update ci status icon ([70c6650](https://github.com/citahub/re-birth/commit/70c665012c9fd2240a0d9e0ec3d589c82296ad66) by classicalliu). -- Rename to rebirth ([02407fe](https://github.com/citahub/re-birth/commit/02407feb80be53502e5cbe51dd1a8a8ec1a98e6c) by classicalliu). -- Update ruby version to 2.5.1 ([0c52de5](https://github.com/citahub/re-birth/commit/0c52de5e6c9328040b2b326346c7a8c21905c444) by classicalliu). -- Test statistics controller ([984217c](https://github.com/citahub/re-birth/commit/984217c0c75ea5deb11d7c556317218b03e4e0d7) by classicalliu). -- Test transactions controller ([d5c6b06](https://github.com/citahub/re-birth/commit/d5c6b06cd13b94c9f0e3b73f2fa006730179705b) by classicalliu). -- Test blocks controller ([d6dc29a](https://github.com/citahub/re-birth/commit/d6dc29a98b6b9a0894ebdde6c29ac31778f513a2) by classicalliu). -- Test cita controller ([e5a7bc7](https://github.com/citahub/re-birth/commit/e5a7bc7fce8c6a7e07bb43b9a644a9dc46f863ca) by classicalliu). -- Test split request controller ([10ed0aa](https://github.com/citahub/re-birth/commit/10ed0aa214c0dc384e255a515cf7a67630b206b4) by classicalliu). -- Test local info controller ([c24c508](https://github.com/citahub/re-birth/commit/c24c50818aada5b94aa4ac12cf55c716471f7184) by classicalliu). -- Test message ([0280738](https://github.com/citahub/re-birth/commit/028073873aa1636143c7dbed578dddd0c78aa13a) by classicalliu). -- Update message get_from method algorithm ([7bb56d8](https://github.com/citahub/re-birth/commit/7bb56d8b1c51b468d771e6505994794e6139e92d) by classicalliu). -- Save block always with transactions ([d41c701](https://github.com/citahub/re-birth/commit/d41c701242f99639612957092caba4ee1d8af9b3) by classicalliu). -- Init issue templates ([d1df18f](https://github.com/citahub/re-birth/commit/d1df18ffffdf9d09d436f30b872a17b81b447d60) by classicalliu). -- Save address with lower case (abi & balance) ([8c9d020](https://github.com/citahub/re-birth/commit/8c9d0206597621726f0f74e1fe96bb870cd3b491) by classicalliu). -- Blocks api ([d9bad54](https://github.com/citahub/re-birth/commit/d9bad548a27cc66e635e87fac24a242e1d69210c) by classicalliu). -- Move controllers to root directory ([d1e4c9f](https://github.com/citahub/re-birth/commit/d1e4c9f6cca494a161a036d6fcab0abd6d5b69a8) by classicalliu). -- Cors support ([43e7af0](https://github.com/citahub/re-birth/commit/43e7af0e7aaef16b0f448eae6565f7d7057a5e51) by classicalliu). -- Sync process ([1cbd340](https://github.com/citahub/re-birth/commit/1cbd34018c723bcff8e4bbe9fceeddce36226f85) by classicalliu). -- Build rpc apis ([d75defd](https://github.com/citahub/re-birth/commit/d75defded398162497e07da5f1c4dfb13168bb0c) by classicalliu). -- Call_rpc method support id and jsonrpc ([288f73a](https://github.com/citahub/re-birth/commit/288f73ae236847a02c8504727562a54fb39eb161) by classicalliu). -- Save block with meta data ([9919425](https://github.com/citahub/re-birth/commit/9919425a43fce664ba87c7e8af5676d90224c6d2) by classicalliu). -- Save abi ([0b0b3e6](https://github.com/citahub/re-birth/commit/0b0b3e62d71a7c6b0d43402181453c2fd67852be) by classicalliu). -- Update ci config ([2687d29](https://github.com/citahub/re-birth/commit/2687d29d282a441982742e60f6c517678d5712bd) by classicalliu). -- Transfer keys methods ([d3eec43](https://github.com/citahub/re-birth/commit/d3eec43c82cb24287bc44f19307ac895c88c2123) by classicalliu). -- Wrapper stub request for rpc call ([0de818f](https://github.com/citahub/re-birth/commit/0de818fcd0200503ded344e7f96fc44e4d36c16e) by classicalliu). -- Update gems, for security problem (github notice) ([189df36](https://github.com/citahub/re-birth/commit/189df3691bc3c1f026aba304c6af79ea9241ca10) by classicalliu). -- Pass all tests (for cita rpc methods name changed) ([3fa595f](https://github.com/citahub/re-birth/commit/3fa595ff33e64324a9860caf510185b2c36633c5) by classicalliu). -- New api methods without prefix in cita 0.16 ([4829c4a](https://github.com/citahub/re-birth/commit/4829c4a3d30f0b6245cff249bef9f88436ee95cc) by classicalliu). -- Test cita sync api ([f8fece7](https://github.com/citahub/re-birth/commit/f8fece7bf6b2e0e79e5a5ae70e34103c987255d2) by classicalliu). -- Cita sync api methods ([5793798](https://github.com/citahub/re-birth/commit/57937985ba569011f14cdb2a08baace6c4699dc1) by classicalliu). -- Config env by dotenv ([f290efe](https://github.com/citahub/re-birth/commit/f290efee7f0745bada2f7d5dd11b1f31b89d250d) by classicalliu). -- Update readme ([dad0296](https://github.com/citahub/re-birth/commit/dad0296c576cbdacc886f12aaa1c38a96bef0a23) by classicalliu). -- Init project ([1dc8f65](https://github.com/citahub/re-birth/commit/1dc8f65bc320235c3230e53bf528bac309b5d992) by classicalliu). - - diff --git a/Gemfile b/Gemfile old mode 100644 new mode 100755 index 70c52a9..027b835 --- a/Gemfile +++ b/Gemfile @@ -1,18 +1,18 @@ -source 'https://rubygems.org' -git_source(:github) { |repo| "https://github.com/#{repo}.git" } +source 'http://mirrors.tuna.tsinghua.edu.cn/rubygems/' +# git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby '2.5.3' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '>= 5.2.2.1' -gem 'nokogiri', '~> 1.11' +gem 'rails', '>= 5.2.5' +gem 'nokogiri', '~> 1.10', '>= 1.10.7' # Use postgresql as the database for Active Record gem 'pg', '>= 0.18', '< 2.0' # Use Puma as the app server -gem 'puma', '~> 3.12.6' +gem 'puma', '~> 3.12.2' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder -# gem 'jbuilder', '~> 2.5' +gem 'jbuilder', '~> 2.5' # Reduces boot times through caching; required in config/boot.rb gem 'bootsnap', '>= 1.1.0', require: false @@ -44,7 +44,7 @@ gem 'rack-cors', require: 'rack/cors' gem 'ransack', '~> 2.0', '>= 2.0.1' # paginate -gem 'kaminari', '~> 1.2' +gem 'kaminari', '~> 1.1', '>= 1.1.1' gem 'google-protobuf', '~> 3.7' @@ -76,6 +76,7 @@ gem 'mina', require: false gem 'mina-puma', require: false gem 'mina-multistage', require: false gem 'mina-sidekiq', '~> 1.0', '>= 1.0.3', require: false +gem "prometheus-client" group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console @@ -102,8 +103,11 @@ end group :test do # mock http request gem 'webmock', '~> 3.4', '>= 3.4.2' - gem 'codecov', '~> 0.1.21', :require => false + gem 'codecov', :require => false end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] + +# gem "sm4", '0.2.4', git: "http://liyi:1111qqqq@192.168.1.210/heyue/sm4.git" +gem "sm_crypto", git: "http://liyi:1111qqqq@192.168.1.210/heyue/sm_crypto.git" \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock old mode 100644 new mode 100755 index 4730868..61a7676 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,25 +1,33 @@ +GIT + remote: http://liyi:1111qqqq@192.168.1.210/heyue/sm_crypto.git + revision: 18646df1b29b517f89428cedbd70fff376b9167b + specs: + sm_crypto (0.1.0) + ffi + json + GEM - remote: https://rubygems.org/ + remote: http://mirrors.tuna.tsinghua.edu.cn/rubygems/ specs: - actioncable (5.2.2.1) - actionpack (= 5.2.2.1) + actioncable (5.2.5) + actionpack (= 5.2.5) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailer (5.2.2.1) - actionpack (= 5.2.2.1) - actionview (= 5.2.2.1) - activejob (= 5.2.2.1) + actionmailer (5.2.5) + actionpack (= 5.2.5) + actionview (= 5.2.5) + activejob (= 5.2.5) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.2.2.1) - actionview (= 5.2.2.1) - activesupport (= 5.2.2.1) - rack (~> 2.0) + actionpack (5.2.5) + actionview (= 5.2.5) + activesupport (= 5.2.5) + rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.2.2.1) - activesupport (= 5.2.2.1) + actionview (5.2.5) + activesupport (= 5.2.5) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) @@ -29,20 +37,20 @@ GEM activemodel (>= 4.1, < 6) case_transform (>= 0.2) jsonapi-renderer (>= 0.1.1.beta1, < 0.3) - activejob (5.2.2.1) - activesupport (= 5.2.2.1) + activejob (5.2.5) + activesupport (= 5.2.5) globalid (>= 0.3.6) - activemodel (5.2.2.1) - activesupport (= 5.2.2.1) - activerecord (5.2.2.1) - activemodel (= 5.2.2.1) - activesupport (= 5.2.2.1) + activemodel (5.2.5) + activesupport (= 5.2.5) + activerecord (5.2.5) + activemodel (= 5.2.5) + activesupport (= 5.2.5) arel (>= 9.0) - activestorage (5.2.2.1) - actionpack (= 5.2.2.1) - activerecord (= 5.2.2.1) - marcel (~> 0.3.1) - activesupport (5.2.2.1) + activestorage (5.2.5) + actionpack (= 5.2.5) + activerecord (= 5.2.5) + marcel (~> 1.0.0) + activesupport (5.2.5) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) @@ -71,13 +79,14 @@ GEM faraday (~> 0.15.3) google-protobuf (~> 3.7) web3-eth (= 0.2.18) - codecov (0.1.21) + codecov (0.1.13) json simplecov + url coderay (1.1.2) composite_primary_keys (11.1.0) activerecord (~> 5.2.1) - concurrent-ruby (1.1.6) + concurrent-ruby (1.1.8) connection_pool (2.2.2) crack (0.4.3) safe_yaml (~> 1.0.0) @@ -91,7 +100,7 @@ GEM dotenv-rails (2.5.0) dotenv (= 2.5.0) railties (>= 3.2, < 6.0) - erubi (1.9.0) + erubi (1.10.0) ethereum.rb (2.2) activesupport (>= 4.0) digest-sha3 (~> 1.1) @@ -110,36 +119,37 @@ GEM health_check (3.0.0) railties (>= 5.0) hiredis (0.6.1) - i18n (1.8.2) + i18n (1.8.9) concurrent-ruby (~> 1.0) jaro_winkler (1.5.1) - json (2.3.0) + jbuilder (2.8.0) + activesupport (>= 4.2.0) + multi_json (>= 1.2) + json (2.1.0) jsonapi-renderer (0.2.0) - kaminari (1.2.1) + kaminari (1.1.1) activesupport (>= 4.1.0) - kaminari-actionview (= 1.2.1) - kaminari-activerecord (= 1.2.1) - kaminari-core (= 1.2.1) - kaminari-actionview (1.2.1) + kaminari-actionview (= 1.1.1) + kaminari-activerecord (= 1.1.1) + kaminari-core (= 1.1.1) + kaminari-actionview (1.1.1) actionview - kaminari-core (= 1.2.1) - kaminari-activerecord (1.2.1) + kaminari-core (= 1.1.1) + kaminari-activerecord (1.1.1) activerecord - kaminari-core (= 1.2.1) - kaminari-core (1.2.1) + kaminari-core (= 1.1.1) + kaminari-core (1.1.1) listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) ruby_dep (~> 1.2) - loofah (2.5.0) + loofah (2.9.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) - marcel (0.3.3) - mimemagic (~> 0.3.2) + marcel (1.0.0) method_source (0.9.2) - mimemagic (0.3.3) mina (1.2.3) open4 (~> 1.3.4) rake @@ -150,13 +160,14 @@ GEM puma (>= 2.13) mina-sidekiq (1.0.3) mina (>= 1.0.2) - mini_mime (1.0.1) + mini_mime (1.0.3) mini_portile2 (2.5.0) - minitest (5.14.1) + minitest (5.14.4) msgpack (1.2.4) + multi_json (1.13.1) multipart-post (2.0.0) - nio4r (2.3.1) - nokogiri (1.11.0) + nio4r (2.5.7) + nokogiri (1.11.2) mini_portile2 (~> 2.5.0) racc (~> 1.4) oj (3.7.0) @@ -166,13 +177,14 @@ GEM ast (~> 2.4.0) pg (1.1.3) powerpack (0.1.2) + prometheus-client (2.0.0) pry (0.11.3) coderay (~> 1.1.0) method_source (~> 0.9.0) pry-rails (0.3.6) pry (>= 0.10.4) public_suffix (3.0.3) - puma (3.12.6) + puma (3.12.2) racc (1.5.2) rack (2.2.3) rack-cors (1.0.5) @@ -181,32 +193,32 @@ GEM rack rack-test (1.1.0) rack (>= 1.0, < 3) - rails (5.2.2.1) - actioncable (= 5.2.2.1) - actionmailer (= 5.2.2.1) - actionpack (= 5.2.2.1) - actionview (= 5.2.2.1) - activejob (= 5.2.2.1) - activemodel (= 5.2.2.1) - activerecord (= 5.2.2.1) - activestorage (= 5.2.2.1) - activesupport (= 5.2.2.1) + rails (5.2.5) + actioncable (= 5.2.5) + actionmailer (= 5.2.5) + actionpack (= 5.2.5) + actionview (= 5.2.5) + activejob (= 5.2.5) + activemodel (= 5.2.5) + activerecord (= 5.2.5) + activestorage (= 5.2.5) + activesupport (= 5.2.5) bundler (>= 1.3.0) - railties (= 5.2.2.1) + railties (= 5.2.5) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) rails-html-sanitizer (1.3.0) loofah (~> 2.3) - railties (5.2.2.1) - actionpack (= 5.2.2.1) - activesupport (= 5.2.2.1) + railties (5.2.5) + actionpack (= 5.2.5) + activesupport (= 5.2.5) method_source rake (>= 0.8.7) thor (>= 0.19.0, < 2.0) rainbow (3.0.0) - rake (13.0.1) + rake (13.0.3) ransack (2.1.1) actionpack (>= 5.0) activerecord (>= 5.0) @@ -265,18 +277,19 @@ GEM spring-watcher-listen (2.0.1) listen (>= 2.7, < 4.0) spring (>= 1.2, < 3.0) - sprockets (3.7.2) + sprockets (4.0.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.2.1) + sprockets-rails (3.2.2) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) - thor (0.20.3) + thor (1.1.0) thread_safe (0.3.6) - tzinfo (1.2.7) + tzinfo (1.2.9) thread_safe (~> 0.1) unicode-display_width (1.4.0) + url (0.3.2) web3-eth (0.2.18) digest-sha3 (~> 1.1.0) rlp (~> 0.7.3) @@ -284,7 +297,7 @@ GEM addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff - websocket-driver (0.7.0) + websocket-driver (0.7.3) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) yard (0.9.20) @@ -301,7 +314,7 @@ DEPENDENCIES byebug ciri-crypto (= 0.1.1) cita-sdk-ruby (~> 0.24.0) - codecov (~> 0.1.21) + codecov composite_primary_keys (~> 11.1) daemons (~> 1.2, >= 1.2.6) database_cleaner @@ -312,20 +325,22 @@ DEPENDENCIES google-protobuf (~> 3.7) health_check (~> 3.0) hiredis (~> 0.6.1) - kaminari (~> 1.2) + jbuilder (~> 2.5) + kaminari (~> 1.1, >= 1.1.1) listen (>= 3.0.5, < 3.2) mina mina-multistage mina-puma mina-sidekiq (~> 1.0, >= 1.0.3) - nokogiri (~> 1.11) + nokogiri (~> 1.10, >= 1.10.7) oj (~> 3.6, >= 3.6.2) pg (>= 0.18, < 2.0) + prometheus-client pry (= 0.11.3) pry-rails - puma (~> 3.12.6) + puma (~> 3.12.2) rack-cors - rails (>= 5.2.2.1) + rails (>= 5.2.5) ransack (~> 2.0, >= 2.0.1) redis (~> 4.0, >= 4.0.3) redis-namespace (~> 1.6) @@ -335,6 +350,7 @@ DEPENDENCIES sidekiq (~> 5.2, >= 5.2.3) sidekiq-bulk (~> 0.2.0) simplecov + sm_crypto! spring spring-watcher-listen (~> 2.0.0) tzinfo-data diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/Makefile b/Makefile old mode 100644 new mode 100755 index 673a8e0..4c423f9 --- a/Makefile +++ b/Makefile @@ -1,7 +1,6 @@ # run this command for first time setup: - docker-compose build - docker-compose run --rm app bundle exec rake db:setup + docker-compose run --rm app bundle exec rake db:setup DISABLE_DATABASE_ENVIRONMENT_CHECK=1 # build images build: @@ -23,7 +22,6 @@ down: # run after update repo update: - docker-compose build docker-compose run --rm app bundle exec rake db:migrate # enter rails console diff --git a/README-CN.md b/README-CN.md old mode 100644 new mode 100755 index b40008c..214bd2e --- a/README-CN.md +++ b/README-CN.md @@ -63,10 +63,6 @@ $ touch .env.test.local (测试环境下不会读取 `.env.local` 中的信息, $ rails spec ``` -`CITA_URL` 默认地址为:localhost:1337 - -初次运行请确认 `CITA_URL` 参数下的链是否真在运行 - ## 执行程序 ```shell @@ -101,71 +97,6 @@ $ mina dev 'rake[daemons:sync:start]' $ bundle exec yard doc $ bundle exec yard server ``` -## 如何查看日志 - -在 `log` 目录下有 `production.log` 和 `sidekiq.log` 文件,可以查看运行日志 -``` -log -├── production.log -└── sidekiq.log -``` ## API 文档 详见 [API Doc](./API_DOC.md) - -## 贡献 - -### 创建 Bug 报告 - -遇到 Bug 时开一个 issue: [https://github.com/citahub/re-birth/issues/new](https://github.com/citahub/re-birth/issues/new) - -并加上你使用的版本信息。 - -### 技术栈 - -通过阅读 [docs/tech_stack.md](docs/tech_stack.md) 了解此项目的编程语言、框架以及开发工具。 - -### 获取源码 - -``` -git clone git@github.com:citahub/re-birth.git -``` - -### 编程风格 - -#### Coding style for Ruby - -* coding style guide: [https://rubystyle.guide](https://rubystyle.guide) -* linter: [RuboCop](https://github.com/bbatsov/rubocop) -* code formatter: $ rubocop -x - - -#### Coding style for Docker - -* coding style guide: https://github.com/Haufe-Lexware/docker-style-guide -* formatter: https://www.fromlatest.io/ -* best-practices: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/ - -#### Coding style for Makefile - -* coding style guide: https://style-guides.readthedocs.io/en/latest/makefile.html -* tutorial: https://makefiletutorial.com/ -* conventions: https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html -* best-practices: https://suva.sh/posts/well-documented-makefiles/ - - -### 运行测试 - -``` -$ rails spec -``` - -### 提交代码 - -#### 代码提交流程 - -[GitHub Flow](https://help.github.com/en/articles/github-flow), [Understanding the GitHub flow](https://guides.github.com/introduction/flow/) - -#### 代码提交规范 - -use [git-style-guide](https://github.com/agis/git-style-guide) for Branches, Commits,Messages, Merging diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 68d5c32..3009756 --- a/README.md +++ b/README.md @@ -55,10 +55,6 @@ $ bundle $ touch .env.local (overwrite `.env` config if you need in `.env.local`, such as DB_USERNAME, DB_PASSWORD and CITA_URL...) $ rails db:setup (or rails db:create db:migrate db:seed) ``` -The default value of `CITA_URL` is: `localhost:1337` - -Please make sure that the cita blockchain is RUNNING - ## Running Test @@ -102,72 +98,5 @@ $ bundle exec yard doc $ bundle exec yard server ``` -##How to view log - -Under `log` folder you can the `production.log` and `sidekiq.log` file -``` -log -├── production.log -└── sidekiq.log -``` - ## API Doc See [API Doc](./API_DOC.md) - - -## Contributing - -### Creating a Bug Report - -open a new issue: [https://github.com/citahub/re-birth/issues/new](https://github.com/citahub/re-birth/issues/new) - -with your version info - -### Tech Stack - -Read [docs/tech_stack.md](docs/tech_stack.md) to know the programming languages, frameworks, and tools that developers use to build this software. - -### Get source - -``` -git clone git@github.com:citahub/re-birth.git -``` - -### Coding style - -#### Coding style for Ruby - -* coding style guide: [https://rubystyle.guide](https://rubystyle.guide) -* linter: [RuboCop](https://github.com/bbatsov/rubocop) -* code formatter: $ rubocop -x - - -#### Coding style for Docker - -* coding style guide: https://github.com/Haufe-Lexware/docker-style-guide -* formatter: https://www.fromlatest.io/ -* best-practices: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/ - -#### Coding style for Makefile - -* coding style guide: https://style-guides.readthedocs.io/en/latest/makefile.html -* tutorial: https://makefiletutorial.com/ -* conventions: https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html -* best-practices: https://suva.sh/posts/well-documented-makefiles/ - - -### Running the tests - -``` -$ rails spec -``` - -### Commit your changes - -#### Workflow - -[GitHub Flow](https://help.github.com/en/articles/github-flow), [Understanding the GitHub flow](https://guides.github.com/introduction/flow/) - -#### git style guide - -use [git-style-guide](https://github.com/agis/git-style-guide) for Branches, Commits,Messages, Merging diff --git a/Rakefile b/Rakefile old mode 100644 new mode 100755 diff --git a/app/channels/application_cable/channel.rb b/app/channels/application_cable/channel.rb old mode 100644 new mode 100755 diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb old mode 100644 new mode 100755 diff --git a/app/controllers/api/blocks_controller.rb b/app/controllers/api/blocks_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/api/decode_transactions_controller.rb b/app/controllers/api/decode_transactions_controller.rb new file mode 100755 index 0000000..c733c8c --- /dev/null +++ b/app/controllers/api/decode_transactions_controller.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class Api::DecodeTransactionsController < ApplicationController + def show + decode_tx = DecodeTransaction.find_by(tx_hash: params[:tx_hash]) + unless decode_tx + return render json: { error_code: 40200, error_message: "不存在的交易或正在排队解析" } + end + + render json: { + contract_address: decode_tx.contract_address, + contract_name: decode_tx.contract_name, + api_name: decode_tx.api_name, + request_args: decode_tx.request_args, + logs: decode_tx.decode_logs.map{|log|log["info"]}, + } + end +end diff --git a/app/controllers/api/erc20_transfers_controller.rb b/app/controllers/api/erc20_transfers_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/api/event_logs_controller.rb b/app/controllers/api/event_logs_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/api/front_end_controller.rb b/app/controllers/api/front_end_controller.rb new file mode 100755 index 0000000..b1af28c --- /dev/null +++ b/app/controllers/api/front_end_controller.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +class Api::FrontEndController < ApplicationController + # before_action :validate_sign + before_action :validate_platform + + def hold_list + open_tongbao = OpenTongbao.find_by(system_id: params[:systemId], tongbao_id: params[:tongbao_id]) + + return render({json: {error_code: 40020, error_message: "无此开立记录"}}) unless open_tongbao + return render({json: {error_code: 40021, error_message: "平台审核未通过"}}) if open_tongbao.platform_agreed == false + return render({json: {error_code: 40022, error_message: "核心企业复核未通过"}}) if open_tongbao.enterprise_agreed == false + return render({json: {error_code: 40023, error_message: "供应商接收接口拒绝接收"}}) if open_tongbao.received == false + return render({json: {error_code: 40024, error_message: "开立撤销"}}) if open_tongbao.cancel_time.present? + return render({json: {error_code: 40025, error_message: "授信已退回"}}) if open_tongbao.back_creditor_time.present? + return render({json: {error_code: 40026, error_message: "平台取消债权开立"}}) if open_tongbao.refuse_time.present? + return render({json: {error_code: 40027, error_message: "平台还未审核"}}) if open_tongbao.platform_time.blank? + return render({json: {error_code: 40028, error_message: "非快速开立,核心企业还未复核"}}) if !open_tongbao.is_quick && open_tongbao.enterprise_time.blank? + return render({json: {error_code: 40029, error_message: "供应商未接收"}}) if open_tongbao.receive_time.blank? + + list = open_tongbao.tongbaos.order(timestamp: :desc).map do |tongbao| + result = tongbao.as_json.slice("hold_id", "amount", "balance", "from_hold_id", "transfer_type", "redeem_amount") + result["institutions_id"] = tongbao.hold_ent_id + result["redeem_time"] = tongbao.redeem_time.try(:timestamp_to_time) + result["pre_redeem_time"] = tongbao.pre_redeem_time.try(:timestamp_to_time) + result["transfer_at"] = tongbao.timestamp.timestamp_to_time + result + end + render json: {hold_list: list, open_amount: open_tongbao.creditor_rights_amount} + end + + def transfer_list + return render({json: {error_code: 40030, error_message: "参数 hold_ids 不能为空"}}) if params[:hold_ids].blank? + tongbaos = Tongbao.where(system_id: params[:systemId], hold_id: params[:hold_ids]) + unlock_tongbao_ids = {} + PledgeTongbao.where(system_id: params[:systemId]). + where("pledge_tb_id_list && ARRAY[?]::varchar[]", params[:hold_ids]). + where(cancel_time: nil).where(is_adopt: [true, nil]). + select(:pledge_id, :pledge_tb_id_list, :unlock_hold_ids, :is_adopt).each do |pledge| + (pledge.pledge_tb_id_list - pledge.unlock_hold_ids.to_a).each do |hold_id| + unlock_tongbao_ids[hold_id] = { pledge_id: pledge.pledge_id } + unlock_tongbao_ids[hold_id][:pledge_status] = (pledge.is_adopt ? "1" : "0") + end + end + list = tongbaos.map do |tongbao| + holder = {hold_id: tongbao.hold_id, tongbao_id: tongbao.tongbao_id} + holder["pledge_id"] = unlock_tongbao_ids[tongbao.hold_id][:pledge_id] if unlock_tongbao_ids[tongbao.hold_id] + holder["pledge_status"] = unlock_tongbao_ids[tongbao.hold_id][:pledge_status] if unlock_tongbao_ids[tongbao.hold_id] + + holder[:transfer_list] = [] + CirculationTongbao.where(system_id: params[:systemId]).applying.where("? = ANY (transfer_tb_id_list)", tongbao.hold_id).each do |circulation_tongbao| + transfer = { + transfer_no: circulation_tongbao.transfer_id, + transfer_type: "流转", + hold_ids: circulation_tongbao.transfer_tb_id_list, + } + holder[:transfer_list] << transfer + end + + FinancingTongbao.where(system_id: params[:systemId]).applying.where("? = ANY (hold_transfer_tb_id_list)", tongbao.hold_id).each do |financing_tongbao| + transfer = { + transfer_no: financing_tongbao.financing_id, + transfer_type: "融资", + hold_ids: financing_tongbao.hold_transfer_tb_id_list, + } + holder[:transfer_list] << transfer + end + + holder + end + + render json: {data: list} + end + +end diff --git a/app/controllers/api/info_controller.rb b/app/controllers/api/info_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/api/ouye_controller.rb b/app/controllers/api/ouye_controller.rb new file mode 100755 index 0000000..439ad0e --- /dev/null +++ b/app/controllers/api/ouye_controller.rb @@ -0,0 +1,61 @@ +class Api::OuyeController < ApplicationController + before_action :validate_platform, except: :platforms + + def platforms + system_ids = Platform.pluck(:system_id) + render json: {systemIds: system_ids} + end + + def credit_total + total_amount = Institution.where(system_id: params[:systemId]).where("credit_limit > 0").sum(:credit_limit).to_6 + used_amount = OpenTongbao.where(redeem_time: nil, received: true, system_id: params[:systemId]).sum(:creditor_rights_amount).to_6 + opening_amount = OpenTongbao.where(system_id: params[:systemId]).applying.sum(:creditor_rights_amount).to_6 + available_amount = (total_amount - used_amount - opening_amount) + render json: { total_amount: total_amount, available_amount: available_amount, used_amount: used_amount, opening_amount: opening_amount } + end + + def credit_list + @ents = Institution.includes(:open_tongbaos).where(system_id: params[:systemId]).where("credit_balance >= 0").order(updated_at: :desc).page(params[:page]).per((params[:per_page] || 10)) + @ents = @ents.where("ent_name like ?", "%#{params["ent_name"]}%") if params["ent_name"].present? + @ents = @ents.where("institutions_id like ?", "%#{params["ent_id"]}%") if params["ent_id"].present? + end + + def ent_open_tongbaos + ent = Institution.find_by(institutions_id: params[:ent_id], system_id: params[:systemId]) + return render({json: {data: []}}) unless ent + @tongbaos = OpenTongbao.where(create_enterprise_id: ent.id, system_id: params[:systemId]).order(apply_time: :desc) + @tongbaos = @tongbaos.applying if params["status"] == "开立中" + @tongbaos = @tongbaos.ended if params["status"] == "开立结束" + @tongbaos = @tongbaos.where(received: true) if params["status"] == "开立成功" + @tongbaos = @tongbaos.where(received: [nil, false]).ended if params["status"] == "开立失败" + @tongbaos = @tongbaos.page(params[:page]).per((params[:per_page] || 10)) + end + + def tongbao_total + total_amount = Tongbao.where(redeem_time: nil, system_id: params[:systemId]).sum(:balance).to_6 + redeem_amount = Tongbao.where(system_id: params[:systemId]).where("redeem_amount > 0").sum(:redeem_amount).to_6 + origin_lock_amount = Tongbao.where(system_id: params[:systemId]).where("lock_amount > 0").sum(:lock_amount) + available_amount = (Tongbao.where(system_id: params[:systemId], redeem_time: nil).sum(:balance) - origin_lock_amount).to_6 + render json: { total_amount: total_amount, redeem_amount: redeem_amount, available_amount: available_amount, lock_amount: origin_lock_amount.to_6 } + end + + def tongbao_list + @tongbaos = Tongbao.where(system_id: params[:systemId]).order(timestamp: :desc) + @tongbaos = @tongbaos.where("tongbao_id like ? escape '\\'", "%#{params["open_no"]}%") if params[:open_no].present? + @tongbaos = @tongbaos.where("hold_id like ? escape '\\'", "%#{params["hold_no"]}%") if params[:hold_no].present? + if params["ent_name"].present? + ent_ids = Institution.where(system_id: params[:systemId]).where("ent_name like ?", "%#{params["ent_name"]}%").pluck(:institutions_id) + @tongbaos = @tongbaos.where(hold_ent_id: ent_ids) + end + @tongbaos = @tongbaos.page(params[:page]).per((params[:per_page] || 10)) + end + + def tongbao_detail + tongbao = Tongbao.find_by!(system_id: params[:systemId], hold_id: params[:hold_no]) + @tongbaos = tongbao.parent_and_sons.where(transfer_type: ["流转", "融资"]).order(timestamp: :desc) + @tongbaos = @tongbaos.where(transfer_type: params[:transfer_type]) if params[:transfer_type].present? + @tongbaos = @tongbaos.page(params[:page]).per((params[:per_page] || 10)) + end + + +end diff --git a/app/controllers/api/platforms_controller.rb b/app/controllers/api/platforms_controller.rb new file mode 100755 index 0000000..e237d80 --- /dev/null +++ b/app/controllers/api/platforms_controller.rb @@ -0,0 +1,24 @@ +class Api::PlatformsController < ApplicationController + def create + if params[:system_id].blank? + return render json: { code: 40301, message: "systemId不能为空" } + end + if params[:admin_id].blank? && (params[:auth_address].blank? || params[:auth_private_key].blank?) + return render json: { code: 40304, message: "请传递转发存证管理员id或授权密钥对参数" } + end + + platform = Platform.find_or_initialize_by(system_id: params[:system_id]) + if params[:admin_id].present? + platform.push_admin_id = params[:admin_id] + platform.begin_push_block = SyncInfo.current_block_number + end + + if params[:auth_address].present? && params[:auth_private_key].present? + platform.auth_address = params[:auth_address].sub(/^0[xX]/, '') + platform.auth_private_key = params[:auth_private_key].sub(/^0[xX]/, '') + end + platform.save! + + render json: {code: 0, message: "成功"} + end +end \ No newline at end of file diff --git a/app/controllers/api/query_cita_controller.rb b/app/controllers/api/query_cita_controller.rb new file mode 100755 index 0000000..31089e2 --- /dev/null +++ b/app/controllers/api/query_cita_controller.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +class Api::QueryCitaController < ApplicationController + before_action :validate_platform + + METHOD_NAMES = { + "getPersonalInfo" => "BackstagePersonnel", #欧冶后台人员信息查询接口 + "getInstitutionsInfo" => "Institutions", #机构信息查询接口 + "getInstitutionsOperatorInfo" => "InstitutionsOperator", #机构操作员信息查询接口 + "getRightsInfo" => "RightsFactory", #授信信息查询接口 + "getAvailableBalance" => "RightsFactory", #获取企业授信可用金额 + "getCreditorAddress" => "RightsFactory", #开立资格查询接口 + "getCreditorRightsInfo" => "CreditorRightsFactory", #开立信息查询接口 + "getCreditorsTransfersApplyInfo" => "CreditorsTransfersFactory", #债权流转查询接口 + "getCreditorsFinancingInfo" => "CreditorsFinancingFactory", #债权融资信息查询 + } + + def index + if params[:contract_address].blank? + return render json: { error_code: 40101, error_message: "contract_address不能为空" } + end + + if params[:method_name].blank? + return render json: { error_code: 40102, error_message: "method_name不能为空" } + end + + unless METHOD_NAMES.keys.include?(params[:method_name]) + return render json: { error_code: 40103, error_message: "不存在的method_name" } + end + + params[:request_params] = params[:request_params].blank? ? [] : params[:request_params] + + unless params[:request_params].instance_of?(Array) + return render json: { error_code: 40104, error_message: "request_params必须是数组" } + end + + abi = ContractAbi.order(:timestamp).where(contract_name: METHOD_NAMES[params[:method_name]], is_static: true).last.abi + unless abi + return render json: { error_code: 40105, error_message: "不能识别的合约地址" } + end + + cita_url = params[:is_pub].to_i == 1 ? ENV["PUB_CITA_URL"] : ENV["CITA_URL"] + cita = CITA::Client.new(cita_url) + contract = cita.contract_at(abi, params[:contract_address]) + + begin + cita_resp = contract.call_func(method: params[:method_name].to_sym, params: params[:request_params]) + rescue Exception => e + Rails.logger.error e.message + Rails.logger.error e.backtrace.to_a + return render json: { error_code: 40106, error_message: "链上返回错误" } + end + + if cita_resp.nil? + return render json: { error_code: 40107, error_message: "不存在的合约地址" } + end + + resp = { result: cita_resp } + + section = abi.find{ |inputs| inputs["name"] == params[:method_name] } + indexs = [] + section["outputs"].each_with_index do |input, index| + indexs << index if input["type"] == "string" + end + return render({json: resp}) if indexs.blank? + + indexs.each do |index| + dicrypted_string = cita_resp[index] + next unless dicrypted_string.instance_of?(String) + json_str = DecodeUtils.try_sm4_dicrypt(dicrypted_string, params[:systemId]) + resp[index] = json_str if json_str + end + + render json: resp + end + +end diff --git a/app/controllers/api/search_controller.rb b/app/controllers/api/search_controller.rb new file mode 100755 index 0000000..dc913d9 --- /dev/null +++ b/app/controllers/api/search_controller.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true + +class Api::SearchController < ApplicationController + before_action :validate_params, except: [:credit_balance, :transfer_tb_balance] + before_action :validate_platform + # before_action :validate_sign + + def establish_total_amount + amount = Tongbao.where(system_id: params[:systemId], transfer_type: "开立").where(timestamp: [params[:startTime]...params[:endTime]]).sum(:amount) + render json: {establishTotalAmount: amount} + end + + def establish_summary + open_tongbaos = OpenTongbao.order(apply_time: :desc).where(system_id: params[:systemId], received: true).where(receive_time: [params[:startTime]...params[:endTime]]) + list = open_tongbaos.map do |open_tongbao| + { + transferTbId: open_tongbao.tongbao_id, + fromEntId: open_tongbao.apply_enterprise_id, + toEntId: open_tongbao.receive_enterprise_id, + amount: open_tongbao.creditor_rights_amount, + establishTime: open_tongbao.receive_time + } + end + render json: {establishSummary: list} + end + + def transfer_summary + tongbaos = Tongbao.where(system_id: params[:systemId], transfer_type: ["流转", "融资"]).where(timestamp: [params[:startTime]...params[:endTime]]).order(timestamp: :desc) + list = tongbaos.map do |tongbao| + { + transferId: tongbao.transfer_no, + fromEntId: tongbao.from_ent_id, + toEntId: tongbao.hold_ent_id, + amount: tongbao.amount, + transferTbId: tongbao.tongbao_id, + holdTransferTbId: tongbao.hold_id, + fromHoldTbId: tongbao.from_hold_id, + transferType: tongbao.transfer_type, + transferTime: tongbao.timestamp + } + end + pledges = PledgeTongbao.where(system_id: params[:systemId], is_adopt: true).where(accept_time: [params[:startTime]...params[:endTime]]).order(accept_time: :desc) + pledges.each do |pledge| + pledge.pledge_tb_id_list.each_with_index do |hold_id, index| + record = { + transferId: pledge.pledge_id, + fromEntId: pledge.apply_enterprise_id, + toEntId: pledge.receive_enterprise_id, + amount: pledge.amount_list[index], + transferTbId: Tongbao.find_by!(system_id: params[:systemId], hold_id: hold_id).tongbao_id, + holdTransferTbId: hold_id, + fromHoldTbId: hold_id, + transferType: "质押", + transferTime: pledge.accept_time + } + list << record + end + end + render json: {transferSummary: list} + end + + def cash_total_amount + amount = Tongbao.where(system_id: params[:systemId], redeem_time: [params[:startTime]...params[:endTime]]).sum(:redeem_amount) + render json: {cashTotalAmount: amount} + end + + def cash_summary + tongbaos = Tongbao.where("balance != 0").includes(:open_tongbao).where(system_id: params[:systemId], redeem_time: [params[:startTime]...params[:endTime]]).order(redeem_time: :desc) + list = tongbaos.map do |tongbao| + { + transferTbId: tongbao.tongbao_id, + fromEntId: tongbao.open_tongbao.apply_enterprise_id, + cashTime: tongbao.redeem_time, + tbHolderId: tongbao.hold_ent_id, + holdTransferTbId: tongbao.hold_id, + tbAmount: tongbao.balance + } + end + render json: {cashSummary: list} + end + + def transfer_tb_balance + tongbaos = Tongbao.where("balance != 0").where(redeem_time: nil, system_id: params[:systemId]).order(timestamp: :desc) + list = tongbaos.map do |tongbao| + { + entId: tongbao.hold_ent_id, + transferTbId: tongbao.tongbao_id, + holdTransferTbId: tongbao.hold_id, + initAmount: tongbao.amount, + AvailableAmount: tongbao.current_balance, + transferAmount: (tongbao.amount - tongbao.balance), + freeze_status: tongbao.freeze_status, + lockAmount: tongbao.lock_amount.to_i + } + end + render json: {transferTblist: list} + end + + def credit_balance + ents = Institution.where("credit_balance >= 0").where(system_id: params[:systemId]).order(updated_at: :desc) + list = ents.map do |ent| + { + entId: ent.institutions_id, + creditLimit: ent.credit_limit, + lockAmount: ent.lock_credit.to_i, + usableAmount: ent.usable_amount, + freeze_status: (ent.freeze_type == 0 ? "冻结" : "正常"), + usedAmount: ent.credit_spent.to_i + } + end + render json: {creditBalance: list} + end + + private + + def validate_params + if params[:startTime].blank? || params[:endTime].blank? + return render json: { error_code: 40003, error_message: "开始时间和结束时间不能为空" } + end + end + +end diff --git a/app/controllers/api/statistics_controller.rb b/app/controllers/api/statistics_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/api/status_controller.rb b/app/controllers/api/status_controller.rb old mode 100644 new mode 100755 index 54f1d41..95a1c3e --- a/app/controllers/api/status_controller.rb +++ b/app/controllers/api/status_controller.rb @@ -3,13 +3,54 @@ class Api::StatusController < ApplicationController # GET /api/status def index - process = system("ruby #{Rails.root.join('lib', 'sync_control.rb')} status") - render json: { + chain_block_number = nil + begin + chain_block_number = CitaSync::Api.block_number["result"]&.hex + rescue Exception => e + end + + sync_info = SyncInfo.find_by(name: "current_block_number") + block_number = sync_info&.value + + sidekiq_processe_size = 0 + begin + sidekiq_processe_size = Sidekiq::ProcessSet.new.size + rescue Exception => e + end + + case + when chain_block_number.nil? + code = 40301 + message = "链无法访问" + when sync_info.blank? || block_number.nil? + code = 40302 + message = "未启动同步进程" + when (chain_block_number == block_number) && (Time.current - sync_info.updated_at) > 50 + code = 40303 + message = "链高度保持不变,链异常" + when (chain_block_number - block_number) < 0 + code = 40304 + message = "链被重置,请停数据服务,并清库清redis" + when (Time.current - sync_info.updated_at) > 50 + code = 40305 + message = "同步服务异常" + when sidekiq_processe_size == 0 + code = 40306 + message = "sidekiq没有正常运行" + else + code = 0 + message = "正常" + end + + status = (code == 0 ? :ok : :internal_server_error) + + render status: status, json: { result: { - status: process ? "running" : "not running", - currentBlockNumber: HexUtils.to_hex(Block.current_block_number || 0), - currentChainBlockNumber: CitaSync::Api.block_number["result"] + code: code, + message: message, + currentBlockNumber: block_number.to_i, + currentChainBlockNumber: chain_block_number } } end diff --git a/app/controllers/api/storages_controller.rb b/app/controllers/api/storages_controller.rb new file mode 100755 index 0000000..dc97c86 --- /dev/null +++ b/app/controllers/api/storages_controller.rb @@ -0,0 +1,9 @@ +class Api::StoragesController < ApplicationController + + def callback + record = StorageRecord.find(params["record_id"]) + data = Oj.load(request.body.read) + record.update!(tx_receipt: data, status: "tx_receipt") + render plain: "SUCCESS" + end +end \ No newline at end of file diff --git a/app/controllers/api/sync_errors_controller.rb b/app/controllers/api/sync_errors_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/api/transactions_controller.rb b/app/controllers/api/transactions_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/api/v2/blocks_controller.rb b/app/controllers/api/v2/blocks_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/api/v2/transactions_controller.rb b/app/controllers/api/v2/transactions_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb old mode 100644 new mode 100755 index 8a7b18b..69fcb64 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -13,7 +13,43 @@ def not_found def homepage render json: { - message: "Read more API interface info at https://github.com/cryptape/re-birth" + message: "北京智汇信元科技有限公司" } end + + private + + def validate_platform + if params[:systemId].blank? + return render json: { error_code: 40004, error_message: "systemId不能为空" } + end + @platform = Platform.find_by(system_id: params[:systemId]) + unless @platform + return render json: { error_code: 40005, error_message: "不存在的systemId" } + end + end + + def validate_sign + if params[:sign].blank? + return render json: { error_code: 40001, error_message: "sign不能为空" } + end + + unless rsa_verify + return render json: { error_code: 40002, error_message: "非法签名" } + end + end + + # x-www-form-urlencoded请求,值都是字符串,所以验签都以字符串对待,签名时要注意。 + def rsa_verify + signed_keys = params.except(:action, :controller, :citum, :sign, params[:controller].split("/").last, :path).keys.sort + sort_params = {} + signed_keys.each{ |param| sort_params[param] = params[param] } + + pub = OpenSSL::PKey::RSA.new(ENV["PUBLIC_KEY"]) + digester = OpenSSL::Digest::SHA1.new + # x-www-form-urlencoded会把加号替换位空字符 + sign = Base64.decode64(params[:sign].gsub(" ", "+")) + return pub.verify(digester, sign, sort_params.to_json) + end + end diff --git a/app/controllers/cita_controller.rb b/app/controllers/cita_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep old mode 100644 new mode 100755 diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb old mode 100644 new mode 100755 diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb old mode 100644 new mode 100755 diff --git a/app/models/application_record.rb b/app/models/application_record.rb old mode 100644 new mode 100755 diff --git a/app/models/backstage_personnel.rb b/app/models/backstage_personnel.rb new file mode 100755 index 0000000..c425b4b --- /dev/null +++ b/app/models/backstage_personnel.rb @@ -0,0 +1,15 @@ +class BackstagePersonnel < ApplicationRecord + self.primary_key = %i(system_id address) + + def self.save_backstage_personnel(log, decode_tx) + personnel = BackstagePersonnel.find_or_initialize_by(system_id: log["info"]["systemId"], address: log["info"]["account"]) + personnel.aes_data = log["info"]["data"] + personnel.extra_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) + personnel.operator_type = log["info"]["operatorType"] + personnel.is_active = log["info"]["setup"] + + personnel.save! + rescue ActiveRecord::RecordNotUnique => e + retry + end +end diff --git a/app/models/block.rb b/app/models/block.rb old mode 100644 new mode 100755 diff --git a/app/models/circulation_tongbao.rb b/app/models/circulation_tongbao.rb new file mode 100755 index 0000000..0138bed --- /dev/null +++ b/app/models/circulation_tongbao.rb @@ -0,0 +1,109 @@ +class CirculationTongbao < ApplicationRecord + self.primary_key = %i(system_id transfer_id) + + scope :applying, -> { where(is_adopt: [true, nil], cancel_time: nil, receive_time: nil, freeze_time: nil, pre_freeze_time: nil) } + + def self.save_circulation_tongbao(log, decode_tx) + begin + circulation_tongbao = CirculationTongbao.find_or_initialize_by(system_id: log["info"]["systemId"], transfer_id: log["info"]["transferId"]) + + case log["abi"]["name"] + when "CTCreditorsTransfer" + circulation_tongbao.aes_data = log["info"]["data"] + circulation_tongbao.extra_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + circulation_tongbao.transfer_tb_id_list = log["info"]["transferTbIdList"] + circulation_tongbao.hold_transferee_tb_id_list = log["info"]["holdTransfereeTbIdList"] + circulation_tongbao.amount_list = log["info"]["amountList"] + circulation_tongbao.recevier_id = log["info"]["receiveEnterprise"] + circulation_tongbao.apply_time = decode_tx.timestamp + when "CTPlatformReview" + circulation_tongbao.aes_review_data = log["info"]["data"] + circulation_tongbao.extra_review_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + circulation_tongbao.is_adopt = log["info"]["accept"] + circulation_tongbao.review_time = decode_tx.timestamp + when "CTCreditorsCancel" + circulation_tongbao.aes_cancel_data = log["info"]["data"] + circulation_tongbao.extra_cancel_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + circulation_tongbao.cancel_time = decode_tx.timestamp + when "CTCreditorsReceive" + circulation_tongbao.aes_receive_data = log["info"]["data"] + circulation_tongbao.extra_receive_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + circulation_tongbao.is_receive = log["info"]["accept"] + circulation_tongbao.receive_time = decode_tx.timestamp + end + + circulation_tongbao.save! + rescue ActiveRecord::RecordNotUnique => e + retry + end + + if log["abi"]["name"] == "CTCreditorsReceive" && log["info"]["accept"] == true + circulation_tongbao.reload.hold_transferee_tb_id_list.each_with_index do |hold_id, index| + begin + ApplicationRecord.transaction(isolation: :serializable) do + Tongbao.create!( + system_id: circulation_tongbao.system_id, + hold_id: hold_id, + from_hold_id: circulation_tongbao.transfer_tb_id_list[index], + hold_ent_id: circulation_tongbao.recevier_id, + amount: circulation_tongbao.amount_list[index], + timestamp: circulation_tongbao.receive_time, + balance: circulation_tongbao.amount_list[index], + transfer_no: circulation_tongbao.transfer_id, + transfer_type: "流转" + ) + end + rescue ActiveRecord::SerializationFailure => e + retry + end + end + end + + circulation_tongbao + end + + def pushing_datas(lock_type, ext_info) + datas = [] + to_ent = Institution.find_by!(system_id: system_id, institutions_id: recevier_id) + transfer_tb_id_list.each_with_index do |from_hold_id, index| + tongbao = Tongbao.find_by!(system_id: system_id, hold_id: from_hold_id) + from_ent = tongbao.hold_ent + biz_type = (to_ent.financial_code.present? && from_ent.financial_code.present?) ? "再流转" : "流转" + + data = { + tongbao_id: tongbao.tongbao_id, + data: { + bizType: biz_type, + operatorType: lock_type, + sendName: from_ent.ent_name, + sendCode: from_ent.institutions_id, + receiveName: to_ent.ent_name, + receiveCode: to_ent.institutions_id, + transactionAmount: amount_list[index].to_6, + endTime: nil, + fromBizDetailNo: from_hold_id, + bizDetailNo: hold_transferee_tb_id_list[index], + bizNo: transfer_id, + extData: ext_info.to_json, + } + } + + datas << data + end + + datas + end + + def pushing_platform_unlock_datas + return [] if is_adopt + pushing_datas("解锁", extra_review_data) + end + + def pushing_receive_datas + datas = pushing_datas("解锁", extra_receive_data) + return datas unless is_receive + datas += pushing_datas("交易成功", extra_receive_data) + + datas + end +end diff --git a/app/models/cita_sync/api.rb b/app/models/cita_sync/api.rb old mode 100644 new mode 100755 diff --git a/app/models/cita_sync/persist.rb b/app/models/cita_sync/persist.rb old mode 100644 new mode 100755 index 0e8d503..4d3feff --- a/app/models/cita_sync/persist.rb +++ b/app/models/cita_sync/persist.rb @@ -29,9 +29,9 @@ def save_block(hex_num_str) return handle_error("getBlockByNumber", rpc_params, error) unless error.nil? # handle for result.nil - # raise "network error, retry later" if result.nil? + raise "network error, retry later" if result.nil? # error is nil now, if result is also nil, means result is nil (like after snapshot) - return if result.nil? + # return if result.nil? block_header = result["header"] block_number_hex_str = block_header["number"] @@ -78,7 +78,7 @@ def save_transaction(tx_data, index, block_number, block_hash, timestamp) # handle error return handle_error("getTransactionReceipt", [hash], receipt_error) unless receipt_error.nil? - return if tx_data.nil? && receipt_result.nil? + # return if tx_data.nil? && receipt_result.nil? # tx_data.nil? 永远不可能为nil message = Message.new(content) transaction = Transaction.new( @@ -114,8 +114,7 @@ def save_transaction(tx_data, index, block_number, block_hash, timestamp) end end - event_log_pkeys = transaction.event_logs.map { |el| [el.transaction_hash, el.transaction_log_index] } - SaveErc20TransferWorker.push_bulk(event_log_pkeys) { |pkey| pkey } + SaveDecodeTransactionWorker.perform_async(hash) if receipt_result["errorMessage"].blank? transaction end @@ -158,13 +157,15 @@ def save_blocks_with_infos default_queue = Sidekiq::Queue.new("default") # current biggest block number in database - last_block_number = SyncInfo.current_block_number || -1 - ((last_block_number + 1)..block_number).each do |num| - break if !Rails.env.test? && (event_loop_queue.size >= 100 || default_queue.size >= 500) - - hex_str = HexUtils.to_hex(num) - SaveBlockWorker.perform_async(hex_str) - SyncInfo.current_block_number = num + ActiveRecord::Base.connection_pool.with_connection do + last_block_number = SyncInfo.current_block_number || -1 + ((last_block_number + 1)..block_number).each do |num| + break if !Rails.env.test? && (event_loop_queue.size >= 100 || default_queue.size >= 500) + + hex_str = HexUtils.to_hex(num) + SaveBlockWorker.perform_async(hex_str) + SyncInfo.current_block_number = num + end end end diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep old mode 100644 new mode 100755 diff --git a/app/models/contract_abi.rb b/app/models/contract_abi.rb new file mode 100755 index 0000000..e5b19b0 --- /dev/null +++ b/app/models/contract_abi.rb @@ -0,0 +1,102 @@ +class ContractAbi < ApplicationRecord + + STORE_ABI_ADDRESS = "0xffffffffffffffffffffffffffffffffff010001" + + EVENT_CONTRACT_INFO = { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "name": "contractName", + "type": "string" + }, + { + "indexed": false, + "name": "contractVersion", + "type": "bytes" + } + ], + "name": "V2ContractInfo", + "type": "event", + "signature": "0x3c120c6bf98e3676bffc4ca90c12d7562e5c07d34a21a40a1e1beca11a591313" + } + + def update_abi_info + return unless is_static + abi_hex = CitaSync::Api.get_abi(address, "pending")["result"] + abi = CITA::Utils.to_bytes(abi_hex) + abi_hash = Oj.load(abi) + + update!(abi: abi_hash) + self + end + + class << self + + def save_deploy_info(transaction) + if transaction.contract_address.present? + begin + contract_abi = ContractAbi.find_or_create_by!(address: transaction.contract_address, is_static: true) + rescue ActiveRecord::RecordNotUnique => e + retry + end + end + + info_logs = transaction.event_logs.to_a.select do |log| + EVENT_CONTRACT_INFO[:signature] == log.topics.first + end + + return if info_logs.blank? + info_logs.sort_by!{ |log| log.transaction_log_index } + info_logs.each do |info_log| + contract_info = DecodeUtils.decode_log(EVENT_CONTRACT_INFO[:inputs], info_log.data, info_log.topics) + contract_abi = ContractAbi.find_or_initialize_by(address: contract_info["contractAddress"]) + contract_abi.contract_name = contract_info["contractName"] + contract_abi.contract_version = contract_info["contractVersion"] + contract_abi.block_number = transaction.block_number + contract_abi.save! + end + end + + def save_abi(transaction) + return unless transaction.to == STORE_ABI_ADDRESS + contract_address = transaction.data[0...42] + begin + contract_abi = ContractAbi.find_or_create_by!(address: contract_address, is_static: true) + rescue ActiveRecord::RecordNotUnique => e + retry + end + contract_abi.update!(block_number: transaction.block_number) + contract_abi.update_abi_info + end + + def save_contract_info(transaction) + return if transaction.error_message.present? + ContractAbi.save_deploy_info(transaction) + ContractAbi.save_abi(transaction) + end + + def get_static_abi(contract_address) + contract_abi = ContractAbi.find_by(address: contract_address) + + return nil unless contract_abi + if !contract_abi.is_static && contract_abi.contract_name.present? + contract_abi = ContractAbi.order(block_number: :desc). + where(contract_name: contract_abi.contract_name, is_static: true, contract_version: contract_abi.contract_version). + where("block_number <= ?", contract_abi.block_number). + first + end + if contract_abi && contract_abi.abi.blank? && contract_abi.contract_name.present? + contract_abi = contract_abi.update_abi_info + end + contract_abi + end + + end + +end diff --git a/app/models/decode_transaction.rb b/app/models/decode_transaction.rb new file mode 100755 index 0000000..533b15e --- /dev/null +++ b/app/models/decode_transaction.rb @@ -0,0 +1,58 @@ +class DecodeTransaction < ApplicationRecord + + belongs_to :tx, foreign_key: "tx_hash", class_name: "Transaction", primary_key: "tx_hash", inverse_of: :decode_tx + + def api_name + request_abi && request_abi["name"] + end + + def contract_address + address = tx.to + address = tx.contract_address if tx.is_deploy_contract? + address + end + + def pretty_params + request_abi["inputs"].map{|input|input["name"]}.zip(request_args).to_h + end + + def auth_mode? + contract_version.match(/\d{8}/)[0] > "20201218" + end + + private + + class << self + + def save_decode_transaction(transaction) + return nil if transaction.error_message.present? + return nil if transaction.to == ContractAbi::STORE_ABI_ADDRESS + return nil if transaction.event_logs.size == 0 + return nil if transaction.is_deploy_contract? + + contract_address = transaction.to + contract_abi = ContractAbi.get_static_abi(contract_address) + return nil if contract_abi.try(:abi).blank? + return nil if contract_abi.contract_name.blank? + web3_abi = Web3::Eth::Contract.new(contract_abi.abi) + request_abi, request_args = transaction.decode_args(web3_abi) + request_params = request_abi["inputs"].map{|input|input["name"]}.zip(request_args).to_h + return nil unless Platform.exists?(system_id: request_params["_systemId"]) + + decode_tx = DecodeTransaction.new + decode_tx.tx_hash = transaction.tx_hash + decode_tx.request_abi = request_abi + decode_tx.request_args = request_args + decode_tx.decode_logs = transaction.decode_logs(web3_abi) + decode_tx.contract_name = contract_abi.contract_name + decode_tx.contract_version = contract_abi.contract_version + decode_tx.timestamp = transaction.timestamp + decode_tx.tx_index = transaction.index + decode_tx.block_number = transaction.block_number + decode_tx.save! + + decode_tx + end + + end +end diff --git a/app/models/erc20_transfer.rb b/app/models/erc20_transfer.rb old mode 100644 new mode 100755 index 1cd0c2c..66d877f --- a/app/models/erc20_transfer.rb +++ b/app/models/erc20_transfer.rb @@ -13,6 +13,7 @@ class Erc20Transfer < ApplicationRecord # validates :event_log, uniqueness: true + # Web3::Eth::Abi::Utils.signature_hash # first of topics: event signature # web3.eth.abi.encodeEventSignature('Transfer(address,address,uint256)') EVENT_TOPIC = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" @@ -52,8 +53,11 @@ def decode(data, topics) # # @param topics [[String]] # @return [true, false] - def transfer?(topics) - topics.include?(EVENT_TOPIC) + def transfer?(event_log) + return false unless event_log.topics.include?(EVENT_TOPIC) + contract_abi = ContractAbi.find_by(address: event_log.address) + return false if contract_abi.try(:contract_name).blank? + true end # create a erc20_transfer from an event log @@ -61,9 +65,10 @@ def transfer?(topics) # @param event_log [EventLog] # @return [Erc20Transfer] def save_from_event_log(event_log) - return unless transfer?(event_log.topics) + return unless transfer?(event_log) info = decode(event_log.data, event_log.topics) + return if info[:value].blank? create!( address: event_log.address, @@ -76,7 +81,8 @@ def save_from_event_log(event_log) from: info[:from], to: info[:to], value: info[:value], - timestamp: event_log.block&.timestamp + contract_name: ContractAbi.find(event_log.address).contract_name, + timestamp: event_log.tx&.timestamp ) end diff --git a/app/models/event_log.rb b/app/models/event_log.rb old mode 100644 new mode 100755 index 81d5a70..d8ed059 --- a/app/models/event_log.rb +++ b/app/models/event_log.rb @@ -16,5 +16,5 @@ class EventLog < ApplicationRecord # same transaction_hash & log_index means same event log validates :transaction_hash, presence: true - validates :transaction_log_index, presence: true, uniqueness: { scope: :transaction_hash } + # validates :transaction_log_index, presence: true, uniqueness: { scope: :transaction_hash } end diff --git a/app/models/event_log_processor.rb b/app/models/event_log_processor.rb old mode 100644 new mode 100755 diff --git a/app/models/financing_tongbao.rb b/app/models/financing_tongbao.rb new file mode 100755 index 0000000..418df17 --- /dev/null +++ b/app/models/financing_tongbao.rb @@ -0,0 +1,115 @@ +class FinancingTongbao < ApplicationRecord + self.primary_key = %i(system_id financing_id) + + scope :applying, -> { where(platform_agreed: [true, nil], cancel_time: nil, accept_time: nil, freeze_time: nil, pre_freeze_time: nil) } + + def self.save_financing_tongbao(log, decode_tx) + begin + financing_tongbao = FinancingTongbao.find_or_initialize_by(system_id: log["info"]["systemId"], financing_id: log["info"]["financingId"]) + case log["abi"]["name"] + when "CreditorsFinancingInfo" + financing_tongbao.aes_data = log["info"]["data"] + financing_tongbao.extra_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + financing_tongbao.financing_amount = log["info"]["financingAmount"] + financing_tongbao.creditors_financing_id = log["info"]["receiveFinancingEnterprise"] + financing_tongbao.hold_transfer_tb_id_list = log["info"]["holdTransferTbIdList"] + financing_tongbao.split_hold_transfer_tb_id_list = log["info"]["splitHoldTransferTbIdList"] + financing_tongbao.amount_list = log["info"]["amountList"] + financing_tongbao.apply_financing_id = log["info"]["applyEnterprise"] + financing_tongbao.apply_time = decode_tx.timestamp + when "PlatformReviewInfo" + financing_tongbao.aes_platform_data = log["info"]["data"] + financing_tongbao.extra_platform_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + financing_tongbao.platform_agreed = log["info"]["agreed"] + financing_tongbao.platform_time = decode_tx.timestamp + when "AcceptFinancingInfo" + financing_tongbao.aes_accept_data = log["info"]["data"] + financing_tongbao.extra_accept_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + financing_tongbao.accept_agreed = log["info"]["agreed"] + financing_tongbao.accept_time = decode_tx.timestamp + when "CancelFinancing" + financing_tongbao.aes_cancel_data = log["info"]["data"] + financing_tongbao.extra_cancel_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + financing_tongbao.cancel_time = decode_tx.timestamp + when "AcceptFinancingSupplement" + financing_tongbao.aes_supplement_data = log["info"]["data"] + financing_tongbao.extra_supplement_data ||= [] + financing_tongbao.extra_supplement_data << Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + financing_tongbao.supplement_time = decode_tx.timestamp + end + + financing_tongbao.save! + rescue ActiveRecord::RecordNotUnique => e + retry + end + + if log["abi"]["name"] == "AcceptFinancingInfo" && log["info"]["agreed"] == true + financing_tongbao.reload.split_hold_transfer_tb_id_list.each_with_index do |hold_id, index| + begin + ApplicationRecord.transaction(isolation: :serializable) do + Tongbao.create!( + system_id: financing_tongbao.system_id, + hold_id: hold_id, + from_hold_id: financing_tongbao.hold_transfer_tb_id_list[index], + hold_ent_id: financing_tongbao.creditors_financing_id, + balance: financing_tongbao.amount_list[index], + amount: financing_tongbao.amount_list[index], + transfer_no: financing_tongbao.financing_id, + timestamp: financing_tongbao.accept_time, + transfer_type: "融资" + ) + end + rescue ActiveRecord::SerializationFailure => e + retry + rescue ActiveRecord::RecordNotUnique + end + end + end + + financing_tongbao + end + + def pushing_datas(lock_type, ext_info) + datas = [] + from_ent = Institution.find_by!(system_id: system_id, institutions_id: apply_financing_id) + to_ent = Institution.find_by!(system_id: system_id, institutions_id: creditors_financing_id) + hold_transfer_tb_id_list.each_with_index do |from_hold_id, index| + tongbao = Tongbao.find_by!(system_id: system_id, hold_id: from_hold_id) + + data = { + tongbao_id: tongbao.tongbao_id, + data: { + bizType: "融资", + operatorType: lock_type, + sendName: from_ent.ent_name, + sendCode: from_ent.institutions_id, + receiveName: to_ent.ent_name, + receiveCode: to_ent.institutions_id, + transactionAmount: amount_list[index].to_6, + endTime: nil, + fromBizDetailNo: from_hold_id, + bizDetailNo: split_hold_transfer_tb_id_list[index], + bizNo: financing_id, + extData: ext_info.to_json, + } + } + + datas << data + end + + datas + end + + def pushing_platform_unlock_datas + return [] if platform_agreed + pushing_datas("解锁", extra_platform_data) + end + + def pushing_receive_datas + datas = pushing_datas("解锁", extra_accept_data) + return datas unless accept_agreed + datas += pushing_datas("交易成功", extra_accept_data) + datas + end + +end diff --git a/app/models/freeze_item.rb b/app/models/freeze_item.rb new file mode 100755 index 0000000..33ec368 --- /dev/null +++ b/app/models/freeze_item.rb @@ -0,0 +1,62 @@ +class FreezeItem < ApplicationRecord + self.primary_key = %i(tx_hash log_index) + + def self.save_freeze_item(log, decode_tx, log_index) + freeze_item = FreezeItem.find_or_initialize_by(tx_hash: decode_tx.tx_hash, log_index: log_index) + freeze_item.system_id = log["info"]["systemId"] + freeze_item.open_tongbao_id = log["info"]["creditorRightsNumID"] + freeze_item.hold_id = log["info"]["holdTransferTbId"] + freeze_item.amount = log["info"]["amount"] + freeze_item.is_freeze = log["info"]["freeze"] + freeze_item.origin_function = log["info"]["originFunction"] + freeze_item.block_number = decode_tx.block_number + freeze_item.save! + + tongbao = Tongbao.find_by!(system_id: freeze_item.system_id, hold_id: log["info"]["holdTransferTbId"]) + case freeze_item.origin_function + when "prePayment" + tongbao.update!(pre_redeem_time: decode_tx.timestamp) + when "payment" + tongbao.update!(redeem_time: decode_tx.timestamp, redeem_amount: freeze_item.amount) + when "freeze" + if freeze_item.is_freeze && decode_tx.block_number > tongbao.freeze_block_number.to_i + tongbao.update!(freeze_block_number: decode_tx.block_number) + end + if !freeze_item.is_freeze && decode_tx.block_number > tongbao.unfreeze_block_number.to_i + tongbao.update!(unfreeze_block_number: decode_tx.block_number) + end + end + end + + def pushing_data(extra_data) + case [origin_function, is_freeze] + when ["freeze", true] + biz_type, operator_type = "异常处理", "冻结" + when ["freeze", false] + biz_type, operator_type = "异常处理", "解冻" + when ["prePayment", true] + biz_type, operator_type = "兑付", "预兑付" + when ["payment", false] + biz_type, operator_type = "兑付", "兑付成功" + end + + tongbao = Tongbao.find_by!(system_id: system_id, hold_id: hold_id) + { + tongbao_id: open_tongbao_id, + data: { + bizType: biz_type, + operatorType: operator_type, + sendName: tongbao.from_ent.ent_name, + sendCode: tongbao.from_ent.institutions_id, + receiveName: tongbao.hold_ent.ent_name, + receiveCode: tongbao.hold_ent.institutions_id, + transactionAmount: amount.to_6, + bizDetailNo: hold_id, + bizNo: (tongbao.transfer_no || open_tongbao_id), + endTime: nil, + fromBizDetailNo: tongbao.from_hold_id, + extData: extra_data.to_json, + } + } + end +end diff --git a/app/models/freeze_tongbao.rb b/app/models/freeze_tongbao.rb new file mode 100755 index 0000000..3dc960d --- /dev/null +++ b/app/models/freeze_tongbao.rb @@ -0,0 +1,39 @@ +class FreezeTongbao < ApplicationRecord + self.primary_key = %i(tx_hash log_index) + + def self.save_freeze_tongbao(log, decode_tx, log_index) + freeze_tongbao = FreezeTongbao.find_or_initialize_by(tx_hash: decode_tx.tx_hash, log_index: log_index) + freeze_tongbao.system_id = log["info"]["systemId"] + freeze_tongbao.tongbao_id = log["info"]["creditorRightsNumID"] + freeze_tongbao.aes_data = log["info"]["data"] + freeze_tongbao.extra_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + freeze_tongbao.transfer_ids = log["info"]["transferIdList"] + freeze_tongbao.financing_ids = log["info"]["financingIdList"] + freeze_tongbao.is_freeze = log["info"]["freeze"] + freeze_tongbao.timestamp = decode_tx.timestamp + freeze_tongbao.block_number = decode_tx.block_number + freeze_tongbao.save! + + if freeze_tongbao.is_freeze + freeze_tongbao.transfer_ids.to_a.each do |transfer_id| + CirculationTongbao.find_by!(system_id: freeze_tongbao.system_id, transfer_id: transfer_id).update!(freeze_time: freeze_tongbao.timestamp) if transfer_id.present? + end + freeze_tongbao.financing_ids.to_a.each do |financing_id| + FinancingTongbao.find_by!(system_id: freeze_tongbao.system_id, financing_id: financing_id).update!(freeze_time: freeze_tongbao.timestamp) if financing_id.present? + end + end + end + + def build_push_datas + datas = [] + if is_freeze + circulation_tongbaos = CirculationTongbao.where(transfer_id: transfer_ids, system_id: system_id) + circulation_tongbaos.each{|ct| datas += ct.pushing_datas("解锁", extra_data)} + financing_tongbaos = FinancingTongbao.where(financing_id: financing_ids, system_id: system_id) + financing_tongbaos.each{|ft| datas += ft.pushing_datas("解锁", extra_data)} + end + + freeze_items = FreezeItem.where(tx_hash: tx_hash).where("amount > 0") + datas += freeze_items.map{|freeze_item| freeze_item.pushing_data(extra_data)} + end +end diff --git a/app/models/institution.rb b/app/models/institution.rb new file mode 100755 index 0000000..8f43c3d --- /dev/null +++ b/app/models/institution.rb @@ -0,0 +1,79 @@ +class Institution < ApplicationRecord + self.primary_key = %i(system_id institutions_id) + + has_many :open_tongbaos, foreign_key: %i(system_id create_enterprise_id), class_name: "OpenTongbao" + + before_save :update_ent_id_and_name + + def update_ent_id_and_name + if self.extra_data_changed? && self.extra_data.present? + self.ent_name = extra_data.to_h["entName"] + end + end + + def opening_amount + self.open_tongbaos.applying.sum(:creditor_rights_amount) + end + + def used_amount + self.open_tongbaos.where(redeem_time: nil, received: true).sum(:creditor_rights_amount) + end + + def children_lock_amount + self.lock_credit.to_i - self.open_tongbaos.applying.where(enterprise_time: nil, is_quick: nil).sum(:creditor_rights_amount) + end + + def usable_amount + self.credit_limit.to_i - self.credit_spent.to_i - self.lock_credit.to_i + end + + def self.save_institution(log, decode_tx) + case log["abi"]["name"] + when "InstitutionsInfo" + institution = Institution.find_or_initialize_by(system_id: log["info"]["systemId"], institutions_id: log["info"]["institutionsId"]) + institution.aes_data = log["info"]["data"] + institution.extra_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + institution.parent_ent_id = log["info"]["parentEntId"] + institution.financial_code = log["info"]["financialCode"] + institution.is_independent = log["info"]["isIndependent"] + institution.is_core_enterprise = log["info"]["isCoreEnterprise"] + institution.open_limit = log["info"]["institutionsAmount"] + when "RightsInfo" + institution = Institution.find_or_initialize_by(system_id: log["info"]["systemId"], institutions_id: log["info"]["institutionsId"]) + institution.credit_aes_data = log["info"]["data"] + institution.credit_extra_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + institution.credit_type = log["info"]["creditType"] + institution.credit_limit = log["info"]["creditLimit"] + institution.credit_start_time = log["info"]["creditStartTime"] + institution.credit_end_time = log["info"]["creditEndTime"] + when "RightsFreezeInfo" + institution = Institution.find_or_initialize_by(system_id: log["info"]["systemId"], institutions_id: log["info"]["institutionsId"]) + institution.freeze_aes_data = log["info"]["data"] + institution.freeze_extra_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + institution.freeze_type = log["info"]["freeze"] + end + institution.save! + rescue ActiveRecord::RecordNotUnique => e + retry + end + + def self.save_rights_amount(log, decode_tx) + begin + ApplicationRecord.transaction(isolation: :serializable) do + institution = Institution.find_or_initialize_by(system_id: log["info"]["systemId"], institutions_id: log["info"]["institutionsId"]) + return if institution.credit_block_number.to_i > decode_tx.block_number + return if institution.credit_block_number == decode_tx.block_number && institution.credit_tx_index > decode_tx.tx_index + + institution.credit_balance = log["info"]["balance"] + institution.credit_spent = log["info"]["spent"] + institution.credit_arrears = log["info"]["totalArrears"] + institution.credit_block_number = decode_tx.block_number + institution.credit_tx_index = decode_tx.tx_index + institution.save! + end + rescue ActiveRecord::SerializationFailure => e + retry + end + end + +end diff --git a/app/models/lock_credit.rb b/app/models/lock_credit.rb new file mode 100755 index 0000000..cb6aca1 --- /dev/null +++ b/app/models/lock_credit.rb @@ -0,0 +1,23 @@ +class LockCredit < ApplicationRecord + + def self.save_lock_credit(log, decode_tx, log_index) + ApplicationRecord.transaction(isolation: :serializable) do + lock_credit = LockCredit.find_or_initialize_by(tx_hash: decode_tx.tx_hash, log_index: log_index) + lock_credit.system_id = log["info"]["systemId"] + lock_credit.rights_lock_limit = log["info"]["rightsLockLimit"] + lock_credit.lock_type = log["info"]["lockType"] + lock_credit.institutions_id = log["info"]["institutionsId"] + lock_credit.open_tongbao_id = log["info"]["creditorRightsNumID"] + lock_credit.origin_function = log["info"]["originFunction"] + lock_credit.timestamp = decode_tx.timestamp + lock_credit.save! + + locked_amount = LockCredit.where(system_id: lock_credit.system_id, institutions_id: lock_credit.institutions_id, lock_type: 0).sum(:rights_lock_limit) + unlocked_amount = LockCredit.where(system_id: lock_credit.system_id, institutions_id: lock_credit.institutions_id, lock_type: 1).sum(:rights_lock_limit) + institution = Institution.find_by!(system_id: lock_credit.system_id, institutions_id: lock_credit.institutions_id) + institution.update!(lock_credit: (locked_amount - unlocked_amount)) + end + rescue ActiveRecord::SerializationFailure => e + retry + end +end diff --git a/app/models/lock_tongbao.rb b/app/models/lock_tongbao.rb new file mode 100755 index 0000000..8eae869 --- /dev/null +++ b/app/models/lock_tongbao.rb @@ -0,0 +1,76 @@ +class LockTongbao < ApplicationRecord + self.primary_key = %i(tx_hash log_index) + + def self.save_lock_tongbao(log, decode_tx, log_index) + ApplicationRecord.transaction(isolation: :serializable) do + lock_tongbao = LockTongbao.find_or_initialize_by(tx_hash: decode_tx.tx_hash, log_index: log_index) + lock_tongbao.system_id = log["info"]["systemId"] + lock_tongbao.tongbao_id = log["info"]["holdTransferTbId"] + lock_tongbao.lock_value = log["info"]["lockValue"] + lock_tongbao.to_ent_id = log["info"]["toInstitutionsId"] + lock_tongbao.is_lock = log["info"]["lock"] + lock_tongbao.origin_function = log["info"]["originFunction"] + lock_tongbao.business_id = log["info"]["businessId"] + lock_tongbao.business_name = log["info"]["businessName"] + lock_tongbao.timestamp = decode_tx.timestamp + lock_tongbao.save! + + total_lock = LockTongbao.where(system_id: lock_tongbao.system_id, tongbao_id: lock_tongbao.tongbao_id, is_lock: true).sum(:lock_value) + total_unlock = LockTongbao.where(system_id: lock_tongbao.system_id, tongbao_id: lock_tongbao.tongbao_id, is_lock: false).sum(:lock_value) + + tongbao = Tongbao.find_by!(system_id: lock_tongbao.system_id, hold_id: log["info"]["holdTransferTbId"]) + tongbao.update!(lock_amount: (total_lock - total_unlock)) + + if log["info"]["businessName"] == "pledge" && log["info"]["lock"] == false + pledge = PledgeTongbao.find_or_initialize_by(system_id: log["info"]["systemId"], pledge_id: log["info"]["businessId"]) + pledge.unlock_hold_ids = (pledge.unlock_hold_ids.to_a << lock_tongbao.tongbao_id) + pledge.save! + end + end + rescue ActiveRecord::SerializationFailure => e + retry + end + + def pushing_data(extra_data) + tongbao = Tongbao.find([system_id, tongbao_id]) + from_ent = tongbao.hold_ent + case business_name + when "pledge" + pledge = PledgeTongbao.find([system_id, business_id]) + to_ent = Institution.find_by!(system_id: system_id, institutions_id: pledge.receive_enterprise_id) + biz_type = "质押" + biz_detail_no = tongbao_id + when "transfer" + circulation = CirculationTongbao.find([system_id, business_id]) + to_ent = Institution.find_by!(system_id: system_id, institutions_id: circulation.recevier_id) + biz_type = (to_ent.financial_code.present? && from_ent.financial_code.present?) ? "再流转" : "流转" + biz_detail_no = circulation.hold_transferee_tb_id_list[circulation.transfer_tb_id_list.find_index(tongbao_id)] + when "financing" + financing = FinancingTongbao.find([system_id, business_id]) + to_ent = Institution.find_by!(system_id: system_id, institutions_id: financing.creditors_financing_id) + biz_type = "融资" + biz_detail_no = financing.split_hold_transfer_tb_id_list[financing.hold_transfer_tb_id_list.find_index(tongbao_id)] + else + raise "非法的锁定类型" + end + + { + tongbao_id: tongbao.tongbao_id, + data: { + bizType: biz_type, + operatorType: (is_lock ? "锁定" : "解锁"), + sendName: from_ent.ent_name, + sendCode: from_ent.institutions_id, + receiveName: to_ent.ent_name, + receiveCode: to_ent.institutions_id, + transactionAmount: lock_value.to_6, + endTime: nil, + fromBizDetailNo: tongbao_id, + bizDetailNo: biz_detail_no, + bizNo: business_id, + extData: extra_data.to_json, + } + } + end + +end diff --git a/app/models/message.rb b/app/models/message.rb old mode 100644 new mode 100755 index 23e7fdc..49f4d7a --- a/app/models/message.rb +++ b/app/models/message.rb @@ -8,7 +8,7 @@ class Message # @param content [String] hex number string of transaction content # @return [void] def initialize(content) - @data = CITA::TransactionSigner.decode(content, recover: false) + @data = CITA::TransactionSigner.decode_content(content, recover: false) @unverified_transaction = @data[:unverified_transaction] @transaction = @unverified_transaction[:transaction] @to = @transaction[:to] diff --git a/app/models/open_tongbao.rb b/app/models/open_tongbao.rb new file mode 100755 index 0000000..84a3361 --- /dev/null +++ b/app/models/open_tongbao.rb @@ -0,0 +1,183 @@ +class OpenTongbao < ApplicationRecord + self.primary_key = %i(system_id tongbao_id) + + has_many :tongbaos, foreign_key: %i(system_id tongbao_id), primary_key: %i(system_id tongbao_id), class_name: "Tongbao" + + belongs_to :create_ent, optional: true, foreign_key: %i(system_id create_enterprise_id), class_name: "Institution" + belongs_to :apply_ent, optional: true, foreign_key: %i(system_id apply_enterprise_id), class_name: "Institution" + belongs_to :receive_ent, optional: true, foreign_key: %i(system_id receive_enterprise_id), class_name: "Institution" + + has_one :hold_tongbao, primary_key: %i(system_id hold_transfer_tb_id), foreign_key: %i(system_id hold_id), class_name: "Tongbao" + + scope :applying, -> { where(platform_agreed: [true, nil], enterprise_agreed: [true, nil], receive_time: nil, cancel_time: nil, back_creditor_time: nil, refuse_time: nil) } + scope :ended, -> { where("platform_agreed = FALSE OR enterprise_agreed = FALSE OR receive_time IS NOT NULL OR cancel_time IS NOT NULL OR back_creditor_time IS NOT NULL OR refuse_time IS NOT NULL") } + + + def apply_operator + operator_id = extra_data && extra_data["fromOperatorId"] + return nil if operator_id.blank? + Operator.find_by(operator_id: operator_id, system_id: system_id) + end + + def status + case + when platform_agreed == false + "平台已拒绝" + when enterprise_agreed == false + "复核已拒绝" + when received == false + "供应商拒绝" + when cancel_time.present? + "企业已撤销" + when back_creditor_time.present? + "授信已退回" + when refuse_time.present? + "平台已撤销" + when !is_quick && enterprise_time.blank? + "等待企业复核" + when platform_time.blank? + "等待平台审核" + when receive_time.blank? + "等供应商接收" + when redeem_time.present? + "已兑付" + when pre_time.present? + "已经预兑付" + when receive_time.present? + "供应商已接收" + end + end + + def self.save_open_tongbao(log, decode_tx) + begin + open_tongbao = OpenTongbao.find_or_initialize_by(system_id: log["info"]["systemId"], tongbao_id: log["info"]["creditorRightsNumID"]) + + case log["abi"]["name"] + when "CreateCreditorRights", "QuickCreateCreditorRights" + open_tongbao.hold_transfer_tb_id = log["info"]["holdTransferTbId"] + open_tongbao.aes_data = log["info"]["data"] + open_tongbao.extra_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + open_tongbao.creditor_rights_amount = log["info"]["creditorRightsAmount"] + open_tongbao.apply_enterprise_id = log["info"]["applyEnterprise"] + open_tongbao.create_enterprise_id = log["info"]["createEnterprise"] + open_tongbao.receive_enterprise_id = log["info"]["receiveEnterprise"] + open_tongbao.is_advance_charge = log["info"]["isPrePayment"] + open_tongbao.invoice_encrypted = [log["info"]["invoice"]] + open_tongbao.invoice_decrypted = [Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["invoice"], log["info"]["systemId"]).to_s)] unless decode_tx.auth_mode? + open_tongbao.payment_date = log["info"]["paymentDate"] + open_tongbao.apply_time = decode_tx.timestamp + open_tongbao.is_quick = true if log["abi"]["name"] == "QuickCreateCreditorRights" + when "PlatformReview" + open_tongbao.platform_time = decode_tx.timestamp + open_tongbao.aes_platform_data = log["info"]["data"] + open_tongbao.extra_platform_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + open_tongbao.platform_agreed = log["info"]["agreed"] + when "EnterpriseReview" + open_tongbao.enterprise_time = decode_tx.timestamp + open_tongbao.aes_enterprise_data = log["info"]["data"] + open_tongbao.extra_enterprise_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + open_tongbao.enterprise_agreed = log["info"]["agreed"] + when "ReceiveCreditorRights" + open_tongbao.receive_time = decode_tx.timestamp + open_tongbao.aes_receive_data = log["info"]["data"] + open_tongbao.extra_receive_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + open_tongbao.received = log["info"]["received"] + when "CancelCreditorRights" #债权开立撤销后,需要调用平台退授信接口 + open_tongbao.cancel_time = decode_tx.timestamp + open_tongbao.aes_cancel_data = log["info"]["data"] + open_tongbao.extra_cancel_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + when "CancelCRPlatformConfirm" # 债权开立撤销后,需要调用平台退授信接口 + open_tongbao.back_creditor_time = decode_tx.timestamp + when "CancelCRByPlatform" + open_tongbao.refuse_time = decode_tx.timestamp + open_tongbao.aes_refuse_data = log["info"]["data"] + open_tongbao.extra_refuse_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + when "UpdateInvoice" + open_tongbao.invoice_encrypted << log["info"]["invoice"] + open_tongbao.invoice_decrypted << Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["invoice"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + end + + open_tongbao.save! + rescue ActiveRecord::RecordNotUnique => e + retry + end + + if log["abi"]["name"] == "ReceiveCreditorRights" && log["info"]["received"] == true + open_tongbao.reload + begin + ApplicationRecord.transaction(isolation: :serializable) do + Tongbao.create!( + system_id: open_tongbao.system_id, + tongbao_id: open_tongbao.tongbao_id, + hold_id: open_tongbao.hold_transfer_tb_id, + from_ent_id: open_tongbao.apply_enterprise_id, + hold_ent_id: open_tongbao.receive_enterprise_id, + amount: open_tongbao.creditor_rights_amount, + timestamp: open_tongbao.receive_time, + balance: open_tongbao.creditor_rights_amount, + transfer_type: "开立" + ) + end + rescue ActiveRecord::SerializationFailure => e + retry + end + + open_tongbao + end + end + + def self.save_redeem_tongbao(log, decode_tx) + begin + open_tongbao = OpenTongbao.find_or_initialize_by(system_id: log["info"]["systemId"], tongbao_id: log["info"]["creditorRightsNumID"]) + case log["abi"]["name"] + when "PrePayment" + open_tongbao.aes_pre_data = log["info"]["data"] + open_tongbao.extra_pre_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + open_tongbao.pre_transfer_ids = log["info"]["transferIdList"] + open_tongbao.pre_financing_ids = log["info"]["financingIdList"] + open_tongbao.pre_time = decode_tx.timestamp + when "Payment" + open_tongbao.aes_redeem_data = log["info"]["data"] + open_tongbao.extra_redeem_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) unless decode_tx.auth_mode? + open_tongbao.redeem_time = decode_tx.timestamp + end + + open_tongbao.save! + rescue ActiveRecord::RecordNotUnique => e + retry + end + + if log["abi"]["name"] == "PrePayment" + open_tongbao.pre_transfer_ids.to_a.each do |transfer_id| + CirculationTongbao.find_by!(system_id: open_tongbao.system_id, transfer_id: transfer_id).update!(pre_freeze_time: decode_tx.timestamp) if transfer_id.present? + end + open_tongbao.pre_financing_ids.to_a.each do |financing_id| + FinancingTongbao.find_by!(system_id: open_tongbao.system_id, financing_id: financing_id).update!(pre_freeze_time: decode_tx.timestamp) if financing_id.present? + end + end + + open_tongbao + end + + def pushing_datas + return [] unless received + data = [{ + tongbao_id: tongbao_id, + data: { + bizType: "开立", + operatorType: "交易成功", + sendName: create_ent.ent_name, + sendCode: create_ent.institutions_id, + receiveName: receive_ent.ent_name, + receiveCode: receive_ent.institutions_id, + transactionAmount: creditor_rights_amount.to_6, + endTime: payment_date.to_s, + bizDetailNo: hold_transfer_tb_id, + fromBizDetailNo: nil, + bizNo: tongbao_id, + extData: extra_receive_data.to_json, + } + }] + end + +end diff --git a/app/models/operator.rb b/app/models/operator.rb new file mode 100755 index 0000000..1a7ab3b --- /dev/null +++ b/app/models/operator.rb @@ -0,0 +1,14 @@ +class Operator < ApplicationRecord + self.primary_key = %i(system_id address) + + def self.save_institutions_operator(log, decode_tx) + operator = Operator.find_or_initialize_by(system_id: log["info"]["systemId"], institutions_id: log["info"]["institutionsId"], address: log["info"]["account"]) + operator.aes_data = log["info"]["data"] + operator.extra_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["data"], log["info"]["systemId"]).to_s) + operator.is_active = log["info"]["setup"] + operator.operator_id = operator.extra_data.to_h["operatorId"] + operator.save! + rescue ActiveRecord::RecordNotUnique => e + retry + end +end diff --git a/app/models/platform.rb b/app/models/platform.rb new file mode 100755 index 0000000..a87f923 --- /dev/null +++ b/app/models/platform.rb @@ -0,0 +1,15 @@ +class Platform < ApplicationRecord + self.primary_key = :system_id + + def self.save_platform_info(log, decode_tx) + platform = Platform.find(log["info"]["systemId"]) + + case log["abi"]["name"] + when "CreatePlatform" + platform.update!({tb_manager: log["info"]["tbManager"], rights_account: log["info"]["rightsAccount"]}) + when "PlatformRightsInfo" + platform.update!({rights_amount: log["info"]["amount"]}) + end + end + +end diff --git a/app/models/pledge_tongbao.rb b/app/models/pledge_tongbao.rb new file mode 100755 index 0000000..deb6679 --- /dev/null +++ b/app/models/pledge_tongbao.rb @@ -0,0 +1,83 @@ +class PledgeTongbao < ApplicationRecord + self.primary_key = %i(system_id pledge_id) + + def self.save_pledge_info(log, decode_tx) + begin + pledge_tongbao = PledgeTongbao.find_or_initialize_by(system_id: log["info"]["_systemId"], pledge_id: log["info"]["_pledgeId"]) + + case log["abi"]["name"] + when "ApplyPledge" + pledge_tongbao.apply_enterprise_id = log["info"]["applyEnterpriseId"] + pledge_tongbao.aes_data = log["info"]["_data"] + pledge_tongbao.extra_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["_data"], log["info"]["_systemId"]).to_s) unless decode_tx.auth_mode? + pledge_tongbao.pledge_tb_id_list = log["info"]["_pledgeTbIdList"] + pledge_tongbao.amount_list = log["info"]["_amountList"] + pledge_tongbao.receive_enterprise_id = log["info"]["_receiveFinancingEnterprise"] + pledge_tongbao.apply_time = decode_tx.timestamp + when "CancelPledge" + pledge_tongbao.aes_cancel_data = log["info"]["_data"] + pledge_tongbao.extra_cancel_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["_data"], log["info"]["_systemId"]).to_s) unless decode_tx.auth_mode? + pledge_tongbao.cancel_time = decode_tx.timestamp + when "AcceptPledge" + pledge_tongbao.aes_accept_data = log["info"]["_data"] + pledge_tongbao.extra_accept_data = Oj.load(DecodeUtils.try_sm4_dicrypt(log["info"]["_data"], log["info"]["_systemId"]).to_s) unless decode_tx.auth_mode? + pledge_tongbao.is_adopt = log["info"]["_accept"] + pledge_tongbao.accept_time = decode_tx.timestamp + end + + pledge_tongbao.save! + rescue ActiveRecord::RecordNotUnique => e + retry + end + end + + def pushing_datas(lock_type, ext_info) + datas = [] + from_ent = Institution.find_by!(system_id: system_id, institutions_id: apply_enterprise_id) + to_ent = Institution.find_by!(system_id: system_id, institutions_id: receive_enterprise_id) + + pledge_tb_id_list.each_with_index do |from_hold_id, index| + tongbao = Tongbao.find_by!(system_id: system_id, hold_id: from_hold_id) + + data = { + tongbao_id: tongbao.tongbao_id, + data: { + bizType: "质押", + operatorType: lock_type, + sendName: from_ent.ent_name, + sendCode: from_ent.institutions_id, + receiveName: to_ent.ent_name, + receiveCode: to_ent.institutions_id, + transactionAmount: amount_list[index].to_6, + endTime: nil, + fromBizDetailNo: from_hold_id, + bizDetailNo: from_hold_id, + bizNo: pledge_id, + extData: ext_info.to_json, + } + } + + datas << data + end + + datas + end + + def pushing_receive_datas + if is_adopt + datas = pushing_datas("交易成功", extra_accept_data) + else + datas = pushing_datas("解锁", extra_accept_data) + end + datas + end + + def pushing_apply_datas + pushing_datas("锁定", extra_data) + end + + def pushing_cancel_datas + pushing_datas("解锁", extra_cancel_data) + end + +end diff --git a/app/models/storage_record.rb b/app/models/storage_record.rb new file mode 100755 index 0000000..c0eeaca --- /dev/null +++ b/app/models/storage_record.rb @@ -0,0 +1,7 @@ +class StorageRecord < ApplicationRecord + # after_create :push_storage_worker + + # def push_storage_worker + # PushStorageWorker.perform_async(id) + # end +end diff --git a/app/models/sync_error.rb b/app/models/sync_error.rb old mode 100644 new mode 100755 diff --git a/app/models/sync_info.rb b/app/models/sync_info.rb old mode 100644 new mode 100755 diff --git a/app/models/tongbao.rb b/app/models/tongbao.rb new file mode 100755 index 0000000..7e42705 --- /dev/null +++ b/app/models/tongbao.rb @@ -0,0 +1,74 @@ +class Tongbao < ApplicationRecord + self.primary_key = %i(system_id hold_id) + + belongs_to :open_tongbao, foreign_key: %i(system_id tongbao_id), class_name: "OpenTongbao", primary_key: %i(system_id tongbao_id), inverse_of: :tongbaos, optional: true + belongs_to :from_ent, foreign_key: %i(system_id from_ent_id), class_name: "Institution", optional: true + belongs_to :hold_ent, foreign_key: %i(system_id hold_ent_id), class_name: "Institution", optional: true + + before_create :set_attrs_from_tongbao + after_create :update_from_tongbao_balance + + def set_attrs_from_tongbao + return if self.from_hold_id.blank? + from_tongbao = Tongbao.find_by!(system_id: system_id, hold_id: from_hold_id) + self.tongbao_id = from_tongbao.tongbao_id + self.from_ent_id = from_tongbao.hold_ent_id + end + + def update_from_tongbao_balance + return if self.from_hold_id.blank? + sons_tongbao_amount = Tongbao.where(system_id: system_id, from_hold_id: from_hold_id).sum(:amount) + from_tongbao = Tongbao.find_by!(system_id: system_id, hold_id: from_hold_id) + from_tongbao.update!(balance: (from_tongbao.amount - sons_tongbao_amount)) + end + + def circulation_tongbao + return nil unless transfer_type == "流转" + CirculationTongbao.find_by!(system_id: system_id, transfer_id: transfer_no) + end + + def financing_tongbao + return nil unless transfer_type == "融资" + FinancingTongbao.find_by!(system_id: system_id, financing_id: transfer_no) + end + + def operator_id + case transfer_type + when "流转" + circulation_tongbao && circulation_tongbao.extra_data["fromOperatorId"] + when "融资" + financing_tongbao && financing_tongbao.extra_data["applyOperatorId"] + when "开立" + open_tongbao.extra_data && open_tongbao.extra_data["fromOperatorId"] + end + end + + def freeze_status + return "已兑付" if redeem_time.present? + return "预兑付冻结" if pre_redeem_time.present? + return "异常冻结" if freeze_block_number.to_i > unfreeze_block_number.to_i + "正常" + end + + def descendant_tongbaos(tongbaos=[]) + son_tongbaos = Tongbao.where(system_id: system_id, from_hold_id: self.hold_id).to_a + tongbaos << self + unless son_tongbaos.size == 0 + son_tongbaos.each do |tongbao| + tongbaos = tongbao.descendant_tongbaos(tongbaos) + end + end + tongbaos + end + + def parent_and_sons + return Tongbao.where("system_id = '#{self.system_id}' AND (hold_id = '#{self.hold_id}' OR from_hold_id = '#{self.hold_id}')") if self.from_hold_id.blank? + Tongbao.where("system_id = '#{self.system_id}' AND (hold_id = '#{self.hold_id}' OR hold_id = '#{self.from_hold_id}' OR from_hold_id = '#{self.hold_id}')") + end + + def current_balance + return (balance - redeem_amount) if redeem_time.present? + return (balance - lock_amount.to_i) + end + +end diff --git a/app/models/transaction.rb b/app/models/transaction.rb old mode 100644 new mode 100755 index c09396d..c964da3 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -8,8 +8,44 @@ class Transaction < ApplicationRecord has_many :event_logs, foreign_key: "transaction_hash", class_name: "EventLog", inverse_of: "tx" has_many :erc20_transfers, foreign_key: "transaction_hash", class_name: "Erc20Transfer", inverse_of: "tx" + has_one :decode_tx, foreign_key: "tx_hash", class_name: "DecodeTransaction", primary_key: "tx_hash", inverse_of: :tx + # validates :block, presence: true - validates :tx_hash, presence: true, uniqueness: true + # validates :tx_hash, presence: true, uniqueness: true alias_attribute :gas_used, :quota_used + + def is_deploy_contract? + # to.blank? || to == "0x0000000000000000000000000000000000000000" # 部署合约 + contract_address.present? # 部署合约 + end + + #Web3::Eth::Abi::Utils.signature_hash("modpow(uint256,uint256,uint256)",8) + def decode_args(web3_abi) + return [nil, nil] if is_deploy_contract? + tx_inputs = web3_abi.functions_by_hash[data[2...10]].abi + inputs = Web3::Eth::Contract::ContractMethod.new(tx_inputs) + params = Web3::Eth::Abi::AbiCoder.decode_abi(inputs.input_types, [data[10..data.length]].pack('H*')) + DecodeUtils.to_utf8!(params) + + [tx_inputs, params] + end + + def decode_logs(web3_abi) + result = [] + contract_address = self.to + event_logs.each do |log| + unless log.address == contract_address + hash_abi = ContractAbi.get_static_abi(log.address).try(:abi) + raise "无法获取#{log.address}的abi信息" unless hash_abi + web3_abi = Web3::Eth::Contract.new(hash_abi) + contract_address = log.address + end + event_abi = web3_abi.events_by_hash[log[:topics].first.gsub("0x", "")].abi + info = DecodeUtils.decode_log(event_abi["inputs"], log.data, log.topics) + result[log.transaction_log_index] = {abi: event_abi, info: info, log_address: log.address} + end + result + end + end diff --git a/app/models/validator_cache.rb b/app/models/validator_cache.rb old mode 100644 new mode 100755 diff --git a/app/serializers/api/block_serializer.rb b/app/serializers/api/block_serializer.rb old mode 100644 new mode 100755 diff --git a/app/serializers/api/erc20_transfer_serializer.rb b/app/serializers/api/erc20_transfer_serializer.rb old mode 100644 new mode 100755 diff --git a/app/serializers/api/event_log_serializer.rb b/app/serializers/api/event_log_serializer.rb old mode 100644 new mode 100755 diff --git a/app/serializers/api/sync_error_serializer.rb b/app/serializers/api/sync_error_serializer.rb old mode 100644 new mode 100755 diff --git a/app/serializers/api/transaction_serializer.rb b/app/serializers/api/transaction_serializer.rb old mode 100644 new mode 100755 diff --git a/app/serializers/block_serializer.rb b/app/serializers/block_serializer.rb old mode 100644 new mode 100755 diff --git a/app/serializers/transaction_serializer.rb b/app/serializers/transaction_serializer.rb old mode 100644 new mode 100755 diff --git a/app/utils/decode_utils.rb b/app/utils/decode_utils.rb old mode 100644 new mode 100755 index 13537b5..798fee3 --- a/app/utils/decode_utils.rb +++ b/app/utils/decode_utils.rb @@ -50,9 +50,37 @@ def decode_log(o_inputs, data, topics) inputs = inputs.each do |input| decoded_data = input[:decoded_data] input[:decoded_data] = "0x" + decoded_data if input[:type] == "address" && !decoded_data.start_with?("0x") + input[:decoded_data].force_encoding("utf-8") if input[:decoded_data].instance_of?(String) + if input[:decoded_data].instance_of?(Array) + input[:decoded_data].each{|item| item.force_encoding("utf-8") if item.instance_of?(String)} + end end (inputs.map.with_index { |input, i| { i => input[:decoded_data] } } + inputs.map { |input| { input[:name] => input[:decoded_data] } }).reduce({}, :merge).with_indifferent_access end + + def to_utf8!(inputs) + inputs.each do |param| + param.remove!("\x00").force_encoding("utf-8") if param.instance_of?(String) + if param.instance_of?(Array) + param.each{|item| item.remove!("\x00").force_encoding("utf-8") if item.instance_of?(String)} + end + end + + inputs + end + + def try_sm4_dicrypt(dicrypted_string, system_id) + cipher_text = Base64.decode64(dicrypted_string).unpack("H*").first + platform = Platform.find(system_id) + decrypt_data = Sm4.decrypt_cbc(cipher_text, platform.sm4_key, platform.sm4_iv) + raise "解密失败" unless decrypt_data.encoding.name == "UTF-8" + raise "非json" unless decrypt_data.blank? || decrypt_data.include?("{") || decrypt_data.include?("[") + decrypt_data + rescue => exception + Rails.logger.error exception.message + return nil + end + end end diff --git a/app/utils/hex_utils.rb b/app/utils/hex_utils.rb old mode 100644 new mode 100755 diff --git a/app/views/api/ouye/credit_list.json.jbuilder b/app/views/api/ouye/credit_list.json.jbuilder new file mode 100755 index 0000000..0694259 --- /dev/null +++ b/app/views/api/ouye/credit_list.json.jbuilder @@ -0,0 +1,13 @@ +json.count @ents.total_count +json.total_pages @ents.total_pages +json.data @ents do |ent| + json.ent_name ent.ent_name + json.ent_id ent.institutions_id + json.init_amount ent.credit_limit.to_i.to_6 + json.available_amount ent.usable_amount.to_6 + json.children_lock_amount ent.children_lock_amount.to_6 + json.start_date ent.credit_start_time&.timestamp_to_time&.to_date.to_s + json.end_date ent.credit_end_time&.timestamp_to_time&.to_date.to_s + json.used_amount ent.used_amount.to_6 + json.opening_amount ent.opening_amount.to_6 +end diff --git a/app/views/api/ouye/ent_open_tongbaos.json.jbuilder b/app/views/api/ouye/ent_open_tongbaos.json.jbuilder new file mode 100755 index 0000000..09c9cb1 --- /dev/null +++ b/app/views/api/ouye/ent_open_tongbaos.json.jbuilder @@ -0,0 +1,14 @@ +json.count @tongbaos.total_count +json.total_pages @tongbaos.total_pages +json.data @tongbaos do |open_tongbao| + json.tongbao_id open_tongbao.tongbao_id + json.apply_ent_id open_tongbao.apply_enterprise_id + json.apply_ent_name open_tongbao.apply_ent.ent_name + json.apply_operator_id open_tongbao.apply_operator.try(:operator_id) + json.receive_ent_id open_tongbao.receive_enterprise_id + json.receive_ent_name open_tongbao.receive_ent.ent_name + json.open_amount open_tongbao.creditor_rights_amount.to_6 + json.hold_id open_tongbao.hold_transfer_tb_id + json.redeem_time open_tongbao.payment_date.try(:timestamp_to_time) + json.status open_tongbao.status +end diff --git a/app/views/api/ouye/tongbao_detail.json.jbuilder b/app/views/api/ouye/tongbao_detail.json.jbuilder new file mode 100755 index 0000000..6bdcdb0 --- /dev/null +++ b/app/views/api/ouye/tongbao_detail.json.jbuilder @@ -0,0 +1,11 @@ +json.count @tongbaos.total_count +json.total_pages @tongbaos.total_pages +json.data @tongbaos do |tongbao| + json.transfer_no tongbao.transfer_no + json.transfer_type tongbao.transfer_type + json.form_ent_id tongbao.from_ent_id + json.hold_ent_id tongbao.hold_ent_id + json.operator_id tongbao.operator_id + json.amount tongbao.amount.to_6 + json.transfer_time tongbao.timestamp.timestamp_to_time +end diff --git a/app/views/api/ouye/tongbao_list.json.jbuilder b/app/views/api/ouye/tongbao_list.json.jbuilder new file mode 100755 index 0000000..a7e7c65 --- /dev/null +++ b/app/views/api/ouye/tongbao_list.json.jbuilder @@ -0,0 +1,13 @@ +json.count @tongbaos.total_count +json.total_pages @tongbaos.total_pages +json.data @tongbaos do |tongbao| + json.ent_name tongbao.hold_ent.ent_name + json.ent_id tongbao.hold_ent_id + json.open_no tongbao.tongbao_id + json.hold_no tongbao.hold_id + json.init_amount tongbao.amount.to_6 + json.balance_amount tongbao.current_balance.to_6 + json.transfer_amount (tongbao.amount - tongbao.balance).to_6 + json.redeem_amount tongbao.redeem_amount.to_i.to_6 + json.lock_amount tongbao.lock_amount.to_i.to_6 +end diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb old mode 100644 new mode 100755 diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb old mode 100644 new mode 100755 diff --git a/app/workers/build_storage_worker.rb b/app/workers/build_storage_worker.rb new file mode 100755 index 0000000..3ac4b62 --- /dev/null +++ b/app/workers/build_storage_worker.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +class BuildStorageWorker + include Sidekiq::Worker + + sidekiq_options queue: "push_storage" + + def perform(tx_hash) + return if StorageRecord.exists?(tx_hash: tx_hash) + decode_tx = DecodeTransaction.find(tx_hash) + system_id = decode_tx.pretty_params["_systemId"] + datas = [] + + case [decode_tx.api_name, decode_tx.contract_name] + # 开立成功 + when ["receiveCreditorRights", "CreditorRights"] + tongbao_id = decode_tx.request_args[1] + open_tongbao = OpenTongbao.find_by!(system_id: system_id, tongbao_id: tongbao_id) + datas = open_tongbao.pushing_datas + # 流转申请 + when ["ctcreditorsTransfer", "CreditorsTransfer"] + circulation_tongbao = CirculationTongbao.find_by!(system_id: system_id, transfer_id: decode_tx.request_args[1]) + datas = circulation_tongbao.pushing_datas("锁定", circulation_tongbao.extra_data) + # 流转撤销 平台或申请方发起 + when ["ctcreditorsCancel", "CreditorsTransfer"], ["ctcreditorsCancelByPlatform", "CreditorsTransfer"] + circulation_tongbao = CirculationTongbao.find_by!(system_id: system_id, transfer_id: decode_tx.request_args[1]) + datas = circulation_tongbao.pushing_datas("解锁", circulation_tongbao.extra_cancel_data) + # 流转平台审核 + when ["ctplatformReview", "CreditorsTransfer"] + circulation_tongbao = CirculationTongbao.find_by!(system_id: system_id, transfer_id: decode_tx.request_args[1]) + datas = circulation_tongbao.pushing_platform_unlock_datas + # 流转供应商接收 + when ["ctcreditorsReceive", "CreditorsTransfer"] + circulation_tongbao = CirculationTongbao.find_by!(system_id: system_id, transfer_id: decode_tx.request_args[1]) + datas = circulation_tongbao.pushing_receive_datas + # 融资申请 + when ["applyCreditorsFinancing", "CreditorsFinancing"] + financing_tongbao = FinancingTongbao.find_by!(system_id: system_id, financing_id: decode_tx.request_args[2]) + datas = financing_tongbao.pushing_datas("锁定", financing_tongbao.extra_data) + # 融资平台审核 + when ["financingPlatformReview", "CreditorsFinancing"] + financing_tongbao = FinancingTongbao.find_by!(system_id: system_id, financing_id: decode_tx.request_args[2]) + datas = financing_tongbao.pushing_platform_unlock_datas + # 融资撤销 + when ["cancelFinancing", "CreditorsFinancing"] + financing_tongbao = FinancingTongbao.find_by!(system_id: system_id, financing_id: decode_tx.request_args[1]) + datas = financing_tongbao.pushing_datas("解锁", financing_tongbao.extra_cancel_data) + # 融资机构接受融资 + when ["acceptFinancing", "CreditorsFinancing"] + financing_tongbao = FinancingTongbao.find_by!(system_id: system_id, financing_id: decode_tx.request_args[2]) + datas = financing_tongbao.pushing_receive_datas + # 冻结/解冻 + when ["freeze", "Payment"] + freeze_info = FreezeTongbao.find_by!(tx_hash: decode_tx.tx_hash) + datas = freeze_info.build_push_datas + # 预兑付/兑付 + when ["prePayment", "Payment"], ["payment", "Payment"] + if decode_tx.api_name == "prePayment" + unlocked_tongbaos = LockTongbao.where(system_id: system_id, tx_hash: decode_tx.tx_hash) + datas = unlocked_tongbaos.map{ |unlocked_tongbao| unlocked_tongbao.pushing_data(nil) } + end + + freeze_items = FreezeItem.where(tx_hash: decode_tx.tx_hash).where("amount > 0") + datas += freeze_items.map{|freeze_item| freeze_item.pushing_data(nil)} + # 质押申请 + when ["applyPledge", "CreditorsPledge"] + pledge_tongbao = PledgeTongbao.find_by!(system_id: system_id, pledge_id: decode_tx.request_args[1]) + datas = pledge_tongbao.pushing_apply_datas + # 质押撤销 + when ["cancelPledge", "CreditorsPledge"] + pledge_tongbao = PledgeTongbao.find_by!(system_id: system_id, pledge_id: decode_tx.request_args[1]) + datas = pledge_tongbao.pushing_cancel_datas + # 质押受理 + when ["acceptPledge", "CreditorsPledge"] + pledge_tongbao = PledgeTongbao.find_by!(system_id: system_id, pledge_id: decode_tx.request_args[1]) + datas = pledge_tongbao.pushing_receive_datas + end + + datas.each do |data| + data[:data].merge!({bizTime: decode_tx.timestamp.to_s}) + end + + records = [] + ApplicationRecord.transaction do + records = datas.map do |data| + StorageRecord.create!({ + tx_hash: decode_tx.tx_hash, + block_number: decode_tx.block_number, + tx_index: decode_tx.tx_index, + token_id: data[:tongbao_id], + data: data[:data], + system_id: system_id, + store_index: SecureRandom.uuid.remove("-"), + }) + end + end + + PushStorageWorker.push_bulk(records.map(&:id)) + end + + +end diff --git a/app/workers/push_storage_worker.rb b/app/workers/push_storage_worker.rb new file mode 100755 index 0000000..821a344 --- /dev/null +++ b/app/workers/push_storage_worker.rb @@ -0,0 +1,43 @@ +class PushStorageWorker + include Sidekiq::Worker + + sidekiq_options queue: "push_storage", retry: 3 + + def perform(stroage_record_id) + record = StorageRecord.find(stroage_record_id) + return if record.status == "tx_receipt" && record.tx_receipt.to_h["code"].to_i == 1 + callback_url = ENV["STORAGE_CALLBACK_URL"] + record.id.to_s + invoke_time = (Time.current.to_f*1000).to_i + platform = Platform.find(record.system_id) + send_params = { + adminId: platform.push_admin_id, + callbackUrl: callback_url, + chainId: ENV["STORAGE_CHAIN_ID"], + dataInfo: record.data.to_json, + invokeTime: invoke_time, + requestSn: "#{record.id.to_s}-#{SecureRandom.uuid}", + systemId: record.system_id, + tokenId: record.token_id, + tokenType: 1, #"应收账款" + } + if ENV["STORAGE_AUTH_PUBKEYS"].present? + send_params.merge!({dataId: record.store_index, authPubKeys: ENV["STORAGE_AUTH_PUBKEYS"].split(";")}) + send_params = send_params.sort.to_h + end + + pri = OpenSSL::PKey::RSA.new(ENV["STORAGE_PRIVATE_KEY"]) + sign = pri.sign('sha1', send_params.to_json) + signature = Base64.encode64(sign) + signature = signature.delete("\n").delete("\r") + send_params[:sign] = signature + + record.update!(request_times: (record.request_times + 1), invoke_time: invoke_time) + uri = URI.parse(ENV["STORAGE_FRONT_URL"]) + resp = Net::HTTP.post(uri, send_params.to_json, "Content-Type" => "application/json") + tx_respond = Oj.load(resp.body) + record.update!(tx_respond: tx_respond, status: "sent_tx") + unless ["1", "50010"].include?(tx_respond["code"].to_s) #"50010" 已经上链成功 + raise "StorageRecord: #{record.id} tx_respond: #{tx_respond.to_json}" + end + end +end diff --git a/app/workers/save_block_worker.rb b/app/workers/save_block_worker.rb old mode 100644 new mode 100755 diff --git a/app/workers/save_decode_transaction_worker.rb b/app/workers/save_decode_transaction_worker.rb new file mode 100755 index 0000000..3e9eeec --- /dev/null +++ b/app/workers/save_decode_transaction_worker.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class SaveDecodeTransactionWorker + include Sidekiq::Worker + + def perform(transaction_hash) + tx = Transaction.find(transaction_hash) + + ContractAbi.save_contract_info(tx) + + decode_tx = DecodeTransaction.save_decode_transaction(tx) + + SaveDecodedInfoWorker.perform_async(transaction_hash) if decode_tx + end + +end diff --git a/app/workers/save_decoded_info_worker.rb b/app/workers/save_decoded_info_worker.rb new file mode 100755 index 0000000..8499f7d --- /dev/null +++ b/app/workers/save_decoded_info_worker.rb @@ -0,0 +1,145 @@ +# frozen_string_literal: true + +class SaveDecodedInfoWorker + include Sidekiq::Worker + + def perform(tx_hash) + + decode_tx = DecodeTransaction.find(tx_hash) + platform = Platform.find_by(system_id: decode_tx.pretty_params["_systemId"]) + return unless platform + + decode_tx.decode_logs.each_with_index do |log, log_index| + case log["abi"]["name"] + when "CreatePlatform", "SetupTBManager", "PlatformRightsInfo" + Platform.save_platform_info log, decode_tx + when "ManagePlatformOperator" + BackstagePersonnel.save_backstage_personnel log, decode_tx + when "InstitutionsInfo", "RightsInfo", "RightsFreezeInfo" + Institution.save_institution log, decode_tx + when "ManageInstitutionsOperator" + Operator.save_institutions_operator(log, decode_tx) + when "CreateCreditorRights", "QuickCreateCreditorRights", "PlatformReview", + "EnterpriseReview", "ReceiveCreditorRights", "CancelCreditorRights", + "CancelCRPlatformConfirm", "CancelCRByPlatform", "UpdateInvoice" + OpenTongbao.save_open_tongbao(log, decode_tx) + when "CTCreditorsTransfer", "CTPlatformReview", "CTCreditorsReceive", "CTCreditorsCancel" + CirculationTongbao.save_circulation_tongbao(log, decode_tx) + when "CreditorsFinancingInfo", "PlatformReviewInfo", "AcceptFinancingInfo", "CancelFinancing", "AcceptFinancingSupplement" + FinancingTongbao.save_financing_tongbao(log, decode_tx) + when "PrePayment", "Payment" + OpenTongbao.save_redeem_tongbao(log, decode_tx) + when "FreezeInfo" + FreezeTongbao.save_freeze_tongbao(log, decode_tx, log_index) + when "FreezeToken" + FreezeItem.save_freeze_item(log, decode_tx, log_index) + when "LockCreditorRights" + LockTongbao.save_lock_tongbao(log, decode_tx, log_index) + when "RightsLockInfo" + LockCredit.save_lock_credit(log, decode_tx, log_index) + when "RightsAmountInfo" + Institution.save_rights_amount(log, decode_tx) + when "ApplyPledge", "CancelPledge", "AcceptPledge" + PledgeTongbao.save_pledge_info(log, decode_tx) + when "DataAuth", "RolesDataAuth" + save_auth_data(log, decode_tx, platform) + end + end + + begin_push_block = platform.begin_push_block + return if begin_push_block.nil? || begin_push_block < 1 + return if begin_push_block > decode_tx.block_number + BuildStorageWorker.perform_async(tx_hash) + end + + def save_auth_data(log, decode_tx, platform) + index = log["info"]["_viewers"].index{ |address| address == platform.auth_address} + return unless index + + auth_key = log["info"]["_keys"].split(",")[index] + cipher = Sm2.decrypt(auth_key[2..-1], platform.auth_private_key) + sm4_key, sm4_iv = cipher[0..31], cipher[32..-1] + + business_id = log["info"]["_businessId"] + system_id = log["info"]["_systemId"] + business_name = log["info"]["_businessName"] + + auth_oj, encrypt_field, decrypt_field = nil, nil , nil + case business_name + when "data.roles.platform" + auth_oj = BackstagePersonnel.find_by!(system_id: system_id, address: log["info"]["_account"]) + encrypt_field, decrypt_field = "aes_data", "extra_data" + when "data.roles.institutions" + auth_oj = Operator.find_by!(system_id: system_id, institutions_id: log["info"]["_institutionsId"], address: log["info"]["_account"]) + decrypt_data = Oj.load(Sm4.decrypt_cbc(Base64.decode64(auth_oj.aes_data).unpack("H*").first, sm4_key, sm4_iv)) + auth_oj.update!(extra_data: decrypt_data, operator_id: decrypt_data["operatorId"]) + return + when "data", "data.initRights", "data.updateRights", "data.rightsFreeze.freeze", "data.rightsFreeze.unfreeze" + return if business_id == "" + auth_oj = Institution.find_by!(system_id: system_id, institutions_id: business_id) + encrypt_field, decrypt_field = "aes_data", "extra_data" if business_name == "data" + encrypt_field, decrypt_field = "credit_aes_data", "credit_extra_data" if ["data.initRights", "data.updateRights"].include?(business_name) + encrypt_field, decrypt_field = "freeze_aes_data", "freeze_extra_data" if ["data.rightsFreeze.freeze", "data.rightsFreeze.unfreeze"].include?(business_name) + when "invoice" #特殊处理invoice提前返回 + auth_oj = OpenTongbao.find_by!(system_id: system_id, tongbao_id: business_id) + invoices = auth_oj.invoice_decrypted.to_a + auth_oj.invoice_encrypted.each_with_index do |encrypt_text, index| + next if invoices[index] + invoices[index] = Oj.load(Sm4.decrypt_cbc(Base64.decode64(encrypt_text).unpack("H*").first, sm4_key, sm4_iv)) + end + auth_oj.update!(invoice_decrypted: invoices) + return + when "data.createCreditorRights", "data.enterpriseReview", "data.platformReview", "data.receiveCreditorRights", + "data.cancelCreditorRights", "data.cancelCreditorRightsByPlatform", "data.prePayment", "data.payment" + auth_oj = OpenTongbao.find_by!(system_id: system_id, tongbao_id: business_id) + encrypt_field, decrypt_field = "aes_data", "extra_data" if business_name == "data.createCreditorRights" + encrypt_field, decrypt_field = "aes_enterprise_data", "extra_enterprise_data" if business_name == "data.enterpriseReview" + encrypt_field, decrypt_field = "aes_platform_data", "extra_platform_data" if business_name == "data.platformReview" + encrypt_field, decrypt_field = "aes_receive_data", "extra_receive_data" if business_name == "data.receiveCreditorRights" + encrypt_field, decrypt_field = "aes_cancel_data", "extra_cancel_data" if business_name == "data.cancelCreditorRights" + encrypt_field, decrypt_field = "aes_refuse_data", "extra_refuse_data" if business_name == "data.cancelCreditorRightsByPlatform" + encrypt_field, decrypt_field = "aes_pre_data", "extra_pre_data" if business_name == "data.prePayment" + encrypt_field, decrypt_field = "aes_redeem_data", "extra_redeem_data" if business_name == "data.payment" + when "data.ctcreditorsTransfer", "data.ctplatformReview", "data.ctcreditorsReceive", "data.ctcreditorsCancel", "data.ctcreditorsCancelByPlatform" + auth_oj = CirculationTongbao.find_by!(system_id: system_id, transfer_id: business_id) + encrypt_field, decrypt_field = "aes_data", "extra_data" if business_name == "data.ctcreditorsTransfer" + encrypt_field, decrypt_field = "aes_review_data", "extra_review_data" if business_name == "data.ctplatformReview" + encrypt_field, decrypt_field = "aes_receive_data", "extra_receive_data" if business_name == "data.ctcreditorsReceive" + # 单独授权,不知道是平台撤销还是申请方撤销 + if ["data.ctcreditorsCancel", "data.ctcreditorsCancelByPlatform"].include?(business_name) + return if decode_tx.request_abi["name"] == "dataAuth" + encrypt_field, decrypt_field = "aes_cancel_data", "extra_cancel_data" + end + when "data.applyCreditorsFinancing", "data.financingPlatformReview", "data.acceptFinancing", "data.cancelFinancing" + auth_oj = FinancingTongbao.find_by!(system_id: system_id, financing_id: business_id) + encrypt_field, decrypt_field = "aes_data", "extra_data" if business_name == "data.applyCreditorsFinancing" + encrypt_field, decrypt_field = "aes_platform_data", "extra_platform_data" if business_name == "data.financingPlatformReview" + encrypt_field, decrypt_field = "aes_accept_data", "extra_accept_data" if business_name == "data.acceptFinancing" + encrypt_field, decrypt_field = "aes_cancel_data", "extra_cancel_data" if business_name == "data.cancelFinancing" + when "data.acceptFinancingSupplement" + return if decode_tx.request_abi["name"] == "dataAuth" + auth_oj = FinancingTongbao.find_by!(system_id: system_id, financing_id: business_id) + decrypt_data = Oj.load(Sm4.decrypt_cbc(Base64.decode64(auth_oj.aes_supplement_data).unpack("H*").first, sm4_key, sm4_iv)) + auth_oj.extra_supplement_data << decrypt_data + auth_oj.save! + return + when "data.applyPledge", "data.cancelPledge", "data.acceptPledge" + auth_oj = PledgeTongbao.find_by!(system_id: system_id, pledge_id: business_id) + encrypt_field, decrypt_field = "aes_data", "extra_data" if business_name == "data.applyPledge" + encrypt_field, decrypt_field = "aes_cancel_data", "extra_cancel_data" if business_name == "data.cancelPledge" + encrypt_field, decrypt_field = "aes_accept_data", "extra_accept_data" if business_name == "data.acceptPledge" + when "data.freeze", "data.unfreeze" + FreezeTongbao.where(system_id: system_id, tongbao_id: business_id).where("extra_data IS NULL").each do |freeze| + decrypt_data = Oj.load(Sm4.decrypt_cbc(Base64.decode64(freeze.aes_data).unpack("H*").first, sm4_key, sm4_iv)) + freeze.update!(extra_data: decrypt_data) + end + return + else + return + end + + decrypt_data = Oj.load(Sm4.decrypt_cbc(Base64.decode64(auth_oj.send(encrypt_field)).unpack("H*").first, sm4_key, sm4_iv)) + auth_oj.update!(decrypt_field => decrypt_data) + end + +end diff --git a/app/workers/save_erc20_transfer_worker.rb b/app/workers/save_erc_transfer_worker.rb old mode 100644 new mode 100755 similarity index 58% rename from app/workers/save_erc20_transfer_worker.rb rename to app/workers/save_erc_transfer_worker.rb index 7374ce2..c003bbf --- a/app/workers/save_erc20_transfer_worker.rb +++ b/app/workers/save_erc_transfer_worker.rb @@ -1,12 +1,12 @@ # frozen_string_literal: true -class SaveErc20TransferWorker +class SaveErcTransferWorker include Sidekiq::Worker def perform(transaction_hash, transaction_log_index) event_log = EventLog.find_by(transaction_hash: transaction_hash, transaction_log_index: transaction_log_index) return if event_log.nil? - Erc20Transfer.save_from_event_log(event_log) if Erc20Transfer.exists?(address: event_log.address&.downcase) && Erc20Transfer.transfer?(event_log.topics) + Erc20Transfer.save_from_event_log(event_log) end end diff --git a/app/workers/save_event_logs_worker.rb b/app/workers/save_event_logs_worker.rb old mode 100644 new mode 100755 diff --git a/app/workers/save_transaction_worker.rb b/app/workers/save_transaction_worker.rb old mode 100644 new mode 100755 diff --git a/bin/cita-cli b/bin/cita-cli new file mode 100755 index 0000000000000000000000000000000000000000..eda3784118f23fa22069756110382c8ef99d76bf GIT binary patch literal 14174248 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 D_y`2VN@2wa1SQ87qehJ8-bd;XbgLF>}c~io)=B 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

|BSSB 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