defmodule BlockScoutWeb.IssuerProfile do @moduledoc """ Blockscout 定制模块:发行方档案页 (P0) 聚合某发行方的所有券批次、保障资金、信用评级 """ alias Explorer.SmartContract.Reader @treasury_abi [ %{ "name" => "getGuaranteeBalance", "type" => "function", "stateMutability" => "view", "inputs" => [%{"name" => "issuer", "type" => "address"}], "outputs" => [%{"name" => "", "type" => "uint256"}] } ] @coupon_factory_abi [ %{ "name" => "getIssuerBatches", "type" => "function", "stateMutability" => "view", "inputs" => [%{"name" => "issuer", "type" => "address"}], "outputs" => [%{"name" => "", "type" => "uint256[]"}] } ] @doc "获取发行方完整档案" def get_issuer_profile(issuer_address, contracts) do %{ address: issuer_address, batches: get_issuer_batches(issuer_address, contracts.coupon_factory), guarantee_fund: get_guarantee_balance(issuer_address, contracts.treasury), total_coupons_issued: count_total_issued(issuer_address, contracts.coupon_factory), active_coupons: count_active_coupons(issuer_address, contracts.coupon_factory), compliance_status: get_compliance_status(issuer_address, contracts.compliance), credit_rating: calculate_credit_rating(issuer_address, contracts) } end @doc "获取发行方的所有券批次" def get_issuer_batches(issuer_address, factory_contract) do case Reader.query_contract(factory_contract, @coupon_factory_abi, %{ "getIssuerBatches" => [issuer_address] }) do %{"getIssuerBatches" => {:ok, [batch_ids]}} -> Enum.map(batch_ids, fn batch_id -> %{ batch_id: batch_id, details: BlockScoutWeb.CouponView.get_batch_summary(batch_id, factory_contract) } end) _ -> [] end end @doc "获取保障资金余额" def get_guarantee_balance(issuer_address, treasury_contract) do case Reader.query_contract(treasury_contract, @treasury_abi, %{ "getGuaranteeBalance" => [issuer_address] }) do %{"getGuaranteeBalance" => {:ok, [balance]}} -> %{raw: balance, formatted: format_stable_amount(balance)} _ -> %{raw: 0, formatted: "0.00"} end end @doc "计算发行方信用评级 (A-D)" def calculate_credit_rating(issuer_address, contracts) do guarantee = get_guarantee_balance(issuer_address, contracts.treasury) total_issued = count_total_issued(issuer_address, contracts.coupon_factory) redemption_rate = get_redemption_rate(issuer_address, contracts) cond do guarantee.raw > total_issued * 0.5 and redemption_rate > 0.95 -> "A" guarantee.raw > total_issued * 0.3 and redemption_rate > 0.85 -> "B" guarantee.raw > total_issued * 0.1 and redemption_rate > 0.70 -> "C" true -> "D" end end # ── 私有函数 ── defp count_total_issued(_issuer, _factory), do: 0 defp count_active_coupons(_issuer, _factory), do: 0 defp get_compliance_status(_issuer, _compliance), do: :compliant defp get_redemption_rate(_issuer, _contracts), do: 1.0 defp format_stable_amount(amount) when is_integer(amount) do # 稳定币 6 位精度 :erlang.float_to_binary(amount / 1_000_000, decimals: 2) end defp format_stable_amount(_), do: "0.00" end