네트워크 자금 기반 계정 온보딩

VP-0001

요약

이 프로그램은 지갑과 애플리케이션이 사용자에게 Vaulta 계정을 무료로, 즉시 제공할 수 있게 합니다. 각 신규 계정에 필요한 RAM은 네트워크 소유 기금에서 기증되므로, 지갑이나 앱은 그 비용을 전혀 부담하지 않습니다. 어떤 지갑이나 앱이든 생성자가 되기 위해 신청할 수 있으며, 프로듀서는 각 생성자를 개별 15/21 MSIG로 승인하고, 기증할 수 있는 양의 상한이 되는 일일 바이트 쿼터(기본값 256 KiB)를 부여합니다.

프로듀서에게 두 건의 15/21 MSIG 승인을 요청합니다. 두 MSIG는 함께 gift.vaulta 계정을 생성하고, 1,000,000,000바이트의 RAM(2026-10-17 가격 기준 약 338,800 EOS 상당)을 admin.grants에서 이 계정으로 옮기며, 승인된 생성자가 자신이 생성하는 계정에 그 RAM을 기증할 수 있게 하는 컨트랙트를 배포합니다. admin.grants는 이전 Foundation 계정으로, 네트워크 자금으로 구매한 RAM을 보유하고 있습니다. 기증된 RAM은 결코 시장에 나오지 않습니다. 수증자는 이를 판매하거나 전송할 수 없으며, 유일한 반출 경로는 gift.vaulta로의 반환이고, gift.vaulta는 반환된 RAM을 다시 기증할 수 있습니다. 컨트랙트와 그 권한에 대한 두 차례의 보안 검토에서 치명적(critical) 또는 높음(high) 등급의 문제는 발견되지 않았습니다. 프로그램은 생성자 없이 출범합니다. 질의응답은 이 프로그램이 RAM 가격에 미치는 영향, fund.wram, 계정 파밍을 다룹니다.

컨트랙트 소스

gift 컨트랙트의 전체 소스 코드는 greymass/vaulta-contracts의 contracts/gift, 커밋 6fad4b0에서 읽을 수 있습니다. 이것은 vp1deploy가 gift.vaulta에 배포하는 바로 그 코드이며, '시행' 항목에서 이를 다시 빌드하고 해시를 확인하는 방법을 설명합니다.

근거

  • 무료 계정: 최소 구성 계정은 2,996바이트의 RAM을 사용하며 그중 1,400바이트는 무료이므로, 계정을 생성하는 쪽은 최소 1,596바이트(2026-10-17 가격 기준 약 0.54 EOS)를, 본 제안이 권장하는 3,000바이트의 경우 약 1.0 EOS어치를 구매해야 합니다. 생성자로 승인된 지갑이나 앱은 admin.grants가 보유한 네트워크 소유 RAM으로 비용을 충당하여 사용자에게 계정을 무료로 즉시 제공합니다.
  • 시장 중립성: 생성자든 수증자든 누구도 기증된 RAM을 판매할 수 없으므로, 기증된 RAM은 RAM 시장에 다시 유입되지 않으며 대량 계정 생성을 토큰으로 전환할 수 없습니다. 생성자가 쿼터를 자신이 통제하는 계정으로 돌려 RAM을 저장 공간으로 사용할 수는 있으며, 일일 쿼터가 그 속도를 제한합니다.
  • 관측된 생성량 기준 비용: 2026-10-17까지 90일 동안 Vaulta에서 생성된 11,082개 계정이 모두 이 프로그램을 통해 생성되었다면, 각 계정이 실제로 받은 RAM에 136바이트 오버헤드를 더해 프로그램은 28.4 MB를 지출했을 것이며, 이는 시드의 2.8%입니다.

시행

시행은 Greymass가 제안하고 순서대로 실행되는 두 건의 MSIG로 이루어지며, 각각 15/21입니다.

  1. vp1create는 eosio::newaccount로 gift.vaulta를 생성하고, eosio가 비용을 지불하여 이 계정에 4,096바이트의 RAM을 구매합니다.
  2. vp1deploy는 gift.vaulta가 존재한 후에 제안되며, ramtransfer로 1,000,000,000바이트 시드를 admin.grants에서 이전하고, halt 및 suspend 권한을 생성하여 해당 액션에 연결하고, limitauthchg를 실행하고, 컨트랙트 코드와 ABI를 설정한 뒤, enable로 끝납니다.

두 MSIG 모두 planned 상태의 msigs 항목으로 선언되어 있고 본 제안의 msig/index.ts로 빌드되며, 각각 180일의 만료 기간으로 제안됩니다.

gift 컨트랙트의 소스 코드는 greymass/vaulta-contracts의 contracts/gift이고, 커밋은 6fad4b08cebfc922b80d09f86cb2590505c22a06이며, 이 커밋은 두 번째 보안 검토가 읽은 커밋인 a9a9a59와 README만 다릅니다. 이 커밋을 Antelope CDT v4.1.1로 make build/gift/production을 통해 빌드하면 sha256이 27ed7ecee18f1a81ec7e9ed4aeacdd76de6e1431f66eb62d363067480ddd3072인 20,977바이트 gift.wasm과 sha256이 17d1ccd52f99782cee42a619dd02cd75c9567d1f716969334ec7f7cf7fbc07f8인 gift.abi가 생성됩니다. vp1deploy는 이 코드를 설정하며, 설정되는 바이너리 ABI의 sha256은 4f39f95e9c4d7d0efb65407ea599f4336656b5075d3d72b3447289b8107590ab로, vp1deploy 실행 후 체인이 gift.vaulta에 대해 보고하는 ABI 해시입니다. Docker와 make가 있으면 누구나 이 바이트를 재현할 수 있습니다. 해당 커밋에서 make build/gift/production은 공식 CDT 4.1.1 릴리스 패키지를 담은 컨테이너 안에서 빌드를 수행하고 gift.wasm과 gift.abi를 contracts/gift/build/에 기록합니다. 동일한 빌드가 Jungle 4 테스트넷의 gift.gm에서 실행되고 있습니다.

Greymass는 커밋 a23b756과 고정 커밋에서 컨트랙트와 권한 설계에 대해 두 차례 보안 검토를 수행했습니다. Anthropic의 Claude Mythos, Fable, Opus가 문제를 찾아 각각을 테스트로 입증했고, Fable과 Opus가 모든 테스트를 다시 실행하여 각 발견 사항을 확인, 수정 또는 반박했습니다. 컨트랙트를 작성하고 두 검토를 모두 수행한 것이 Greymass이므로, 어느 검토도 작성자로부터 독립적이지 않습니다. 두 검토 모두 치명적 또는 높음 등급의 문제를 발견하지 않았으며, 모든 발견 사항은 본 제안의 본문, 시행 단계 또는 운영 규칙에서 해소되었거나 그 사유와 함께 수용되었습니다. 보안 검토에 모든 발견 사항이 나열되어 있습니다. 프로듀서가 네트워크 자금으로 추가 검토를 지원하는 것을 환영하며, 어느 팀이든 고정 커밋의 소스를 검토할 수 있습니다.

기증 방식

생성자는 하나의 트랜잭션에서 계정을 생성하고 RAM을 기증합니다.

  1. eosio::newaccount: 통상적인 프리미엄 이름 규칙에 따라 새 이름의 접미사를 소유한 계정이 서명합니다(gm이 foo.gm을 생성).
  2. gift.vaulta::giftacct(creator, account, bytes, memo): 생성자가 서명합니다. 컨트랙트는 생성자와 그 쿼터를 확인한 뒤, gift.vaulta에서 신규 계정으로 bytes만큼의 인라인 eosio::giftram을 전송합니다.

컨트랙트는 같은 트랜잭션의 최상위 newaccount가 생성하는 계정에 대해서만 기증을 허용하므로, 프로그램은 신규 계정에만 도달하며, 컨트랙트 코드가 생성하거나 msig exec 안에서 생성된 계정은 기증을 받을 수 없습니다(giftacct 자체는 인라인으로 도착할 수 있습니다. 기술 참고 사항 참고). 컨트랙트는 누가 newaccount에 서명했는지 확인하지 않습니다. 따라서 생성자는 접미사 소유자가 서명하는 경우 자신이 소유하지 않은 접미사 아래의 이름에도 자금을 댈 수 있고, 한 생성자가 하나의 쿼터로 여러 접미사를 사용할 수 있습니다. 예를 들어 gm으로 등록되어 있고 jm도 소유한 생성자는 newaccount에 jm으로, giftacct에 gm으로 서명하여 bob.jm을 생성하며, 이 기증은 gm의 쿼터에서 차감됩니다.

계정을 생성하는 최소 기증량은 1,596바이트입니다. 최소 구성 계정은 2,996바이트를 사용하고, 계정이 RAM을 조금이라도 보유하면 시스템이 1,400바이트를 무료로 추가하기 때문입니다. 생성자는 최소 3,000바이트를 기증할 것을 권장하며, 이 양은 계정 자체의 EOS 및 A 토큰 잔액(240바이트 및 241바이트)과 첫 REX 스테이크(489바이트)까지 충당하고도 약 434바이트가 남습니다. 각 기증의 크기는 생성자가 정하며, 예를 들어 앱 자체의 상태를 저장할 만큼 더 많이 기증할 수도 있습니다.

기증은 RAM만 늘리므로 신규 계정은 NET이나 CPU 없이 시작합니다. 생성자는 자신이 생성하는 다른 계정과 마찬가지로 사용자를 위해 스테이크하거나, 파워업하거나, 사용자의 트랜잭션 비용을 지불합니다.

쿼터

각 생성자에게는 일일 바이트 쿼터가 있으며, 각 기증은 기증된 바이트에 136바이트를 더한 만큼 쿼터에서 차감됩니다. 136바이트는 시스템 컨트랙트가 수증자마다 기증자에게 청구하는 행의 크기로, 컨트랙트에 고정된 상수입니다. 따라서 쿼터는 기금이 실제로 지출하는 양을 제한합니다.

  • 신규 승인 생성자의 기본 쿼터는 하루 262,144바이트(256 KiB)로, 최소 기증 기준 약 150개 계정, 3,000바이트 기준 약 83개 계정에 해당합니다. 2026-10-17까지 90일 동안 Vaulta에서 꾸준히 계정을 생성한 생성자 중 가장 활발했던 pcash는 하루 최대 59개 계정을 생성했으며, 계정당 1,600바이트에 136바이트를 더하면 102,424바이트의 쿼터를 사용하게 됩니다. gm은 계정당 3,000바이트로 하루 최대 29개를 생성했으며, 이는 90,944바이트를 사용하게 됩니다. 더 큰 수요를 입증하는 생성자는 신청서에서 더 큰 쿼터를 요청하며, 이후의 모든 변경은 15/21 setquota로 이루어집니다.
  • 쿼터는 최소 1,972바이트여야 합니다. 이는 자체 토큰 잔액 하나를 위한 공간을 갖춘 최소 구성 계정을 생성하는 1,836바이트 기증 1건에 136바이트를 더한 값입니다.
  • 생성자의 24시간 윈도우는 첫 기증 시점에 시작되고, 그로부터 24시간 이상 지난 뒤의 첫 기증 시점에 리셋되며, 초 단위로 계산됩니다. 따라서 생성자는 리셋 직전에 한 번, 직후에 한 번, 한 블록 간격 안에 쿼터 전량을 두 번 지출할 수 있습니다.
  • 생성자 전체에 걸친 상한은 없습니다. 프로그램이 하루에 지출할 수 있는 최대량은 모든 쿼터의 합계이며, 이는 프로듀서가 생성자를 승인하거나 쿼터를 증액할 때만 증가하고, 두 경우 모두 15/21이 필요합니다.
  • 생성자를 제거했다가 재승인하면 현재 윈도우의 사용량이 리셋되고 정지 상태도 해제되며, setquota는 둘 다 유지합니다.
  • 기증이 남은 쿼터를 초과하거나, 프로그램이 비활성화되었거나, 생성자가 정지된 경우, 생성자는 기존 방식으로 계정을 생성하고 buyrambytes 또는 자체 giftram으로 RAM 비용을 직접 부담하므로, 사용자의 가입은 계속됩니다.

컨트랙트 액션

액션 권한 목적
giftacct(creator, account, bytes, memo) creator 같은 트랜잭션에서 생성된 계정에 gift.vaulta의 bytes를 기증하고 생성자의 쿼터에서 차감
addcreator(creator, daily_quota_bytes) gift.vaulta@active (15/21) 일일 쿼터와 함께 생성자 등록
rmcreator(creator) gift.vaulta@active (15/21) 생성자 제거
setquota(creator, daily_quota_bytes) gift.vaulta@active (15/21) 생성자의 쿼터 변경
enable() gift.vaulta@active (15/21) 등록된 생성자의 RAM 기증 허용
disable() gift.vaulta@halt (11/21) 모든 기증을 중지하고 모든 등록을 유지
suspend(creator) gift.vaulta@suspend (8/21) 한 생성자의 기증을 중지하고 그 등록을 유지
resume(creator) gift.vaulta@halt (11/21) 생성자의 정지 해제

컨트랙트는 배포 시 꺼져 있는 enabled 플래그를 유지하므로, enable이 통과될 때까지 아무것도 기증하지 않습니다. giftacct는 생성자의 권한을 확인한 다음 플래그를 확인하므로, disable은 모든 생성자를 한 번에 중지시킵니다. 정지된 생성자의 기증은 실패합니다. 그 생성자의 등록, 쿼터, 사용량, 윈도우 시작 시각은 변경되지 않으며, resume으로 다시 기증할 수 있게 되고, rmcreator는 그 행을 삭제합니다. 각 생성자의 쿼터, 사용량, suspended 필드는 컨트랙트의 creators 테이블에 공개되어 있으며, 모든 기증은 공개된 giftacct 액션입니다.

기금

시드는 1,000,000,000바이트이며, ramtransfer로 admin.grants에서 이전됩니다. 이는 2026-10-17 기준 admin.grants가 보유한 2,812,891,144바이트 RAM 쿼터의 3분의 1 이상에 해당하며, admin.grants는 그날까지 ramtransfer로 다른 계정에 RAM을 281회 이전했습니다. 이후의 모든 보충 역시 ramtransfer를 사용합니다. giftram으로 gift.vaulta에 보낸 RAM은 그곳에 잠긴 채로 남아 다시 기증할 수 없기 때문입니다. 그러한 RAM을 해제하려면 15/21 ungiftram이 필요하며, 이는 기증분 전체를 그 기증자에게 반환합니다. 그로 인해 gift.vaulta의 자체 RAM이 1,400바이트를 초과하는 사용량을 더 이상 충당하지 못하게 되는 경우, 같은 트랜잭션에서 먼저 ramtransfer로 그만큼의 RAM을 gift.vaulta에 보냅니다.

최소 구성 계정에는 약 1,600바이트의 기증이 필요하고, 사용자에게 작업할 여유를 남겨 주는 생성자는 최대 약 3,300바이트를 기증하므로, 136바이트 오버헤드를 포함하면 시드는 약 290,000개에서 580,000개의 계정을 충당합니다. 기증이 클수록 충당하는 계정 수는 줄어듭니다. signup.xsat이 giftram으로 자금을 대는 각 계정에 주는 6,144바이트 기준으로는 약 159,000개입니다. 2026-10-17까지 90일 동안 체인의 모든 생성자에 걸쳐 Vaulta에서 관측된 생성량 기준으로, 시드는 9년 가까이 지속됩니다. 최악의 경우는 자기거래로, 모든 생성자가 매일 자신이 통제하는 계정에 쿼터 전량을 지출하는 경우입니다. 기본값 256 KiB의 생성자 10곳은 약 380일 만에 시드를 소진하며, 프로듀서는 그보다 훨씬 전에 그중 어느 생성자든 정지시킬 수 있습니다.

보충은 별도의 15/21 MSIG로, 그 자체의 타당성에 따라 결정됩니다. 프로듀서는 disable로 프로그램을 종료하고, gift.vaulta로부터의 15/21 ramtransfer로 그 RAM을 admin.grants에 반환할 수도 있습니다. 이 이전은 다음 두 양 중 더 큰 쪽을 제외한 전부를 옮깁니다. 하나는 gift.vaulta의 1,400 무료 바이트를 초과하는 자체 사용량(코드, ABI, 테이블, 그리고 반환되지 않은 기증마다 136바이트 행)을 충당하는 바이트이고, 다른 하나는 gift.vaulta에 기증된 RAM입니다. 이후에 반환되는 기증은 gift.vaulta에 도착하며 추가 ramtransfer로 옮겨집니다.

쿼터는 일일 소진량을 제한하며, 시드가 모두 지출되면 기증은 중지됩니다. gift.vaulta는 자체 코드, ABI, 테이블 비용(출범 시 216,918바이트)을 부담하므로, 성사되는 최대 기증은 gift.vaulta의 RAM 잔액에 1,400 무료 바이트를 더하고 그 사용량과 136바이트 오버헤드를 뺀 값이며, gift.vaulta 잔액 중 215,654바이트는 결코 기증할 수 없습니다. 그보다 1바이트 큰 기증은 account gift.vaulta has insufficient ram 오류로 실패합니다. 그러면 모든 생성자의 기증이 한 번에 중지되므로, 한 생성자의 지출이 다른 생성자의 서비스를 끝낼 수 있습니다. 새 레지스트리 행에 RAM이 필요하므로 addcreator도 실패하며, disable, enable, suspend, resume, setquota, rmcreator는 계속 작동합니다.

생성자 되기

승인에는 addcreator(creator, daily_quota_bytes)를 담아 통과된 15/21 BP MSIG가 필요하며, 이 MSIG의 첫 번째 액션은 생성자의 신청서를 링크하는 msigmessager::message입니다.

신청서는 어디에나 게시할 수 있습니다. greymass/vaulta-proposals GitHub 저장소에 생성자 VP로 제출하는 것을 권장합니다. VP는 프로듀서에게 검토 가능한 영구 문서를 제공하고 msig에 인용 근거를 제공하기 때문입니다. 이 저장소의 template/creator/에는 신청 양식과 addcreator msig 빌더가 있습니다. 모든 신청서는 다음 여섯 개의 필수 항목에 답합니다.

  1. 신원: 등록할 계정과 그 운영 주체.
  2. 용도와 쿼터: giftacct를 호출할 제품, 계정당 기증할 바이트 수와 그 이유, 예상 생성량 중 무료와 유료의 비율, 그리고 현재 생성량의 근거를 포함한 요청 일일 쿼터.
  3. 실제 사용자: 최종 사용자가 제시해야 하는 것과 생성자의 서버가 이를 검증하는 방법, 사람, 기기, IP 주소, 일 단위로 적용하는 상한과 각 상한의 기준이 되는 식별자, 별칭 및 일회용 신원의 처리 방법, 그리고 적용하는 이름 규칙.
  4. 트랜잭션 구조: 최상위 eosio::newaccount 다음에 giftacct가 오는 구조. giftacct를 전송하는 방법(생성자의 키로 서명, 생성자가 승인하는 msig를 통해, 또는 생성자가 배포하는 컨트랙트를 통해. 컨트랙트의 경우 누가 호출할 수 있고 무엇이 그 호출자를 제한하는지), 제3자가 newaccount에 서명하는 계정에도 생성자가 자금을 대는지 여부, 요청이 쿼터를 두 번 지출하지 않도록 재시도의 멱등성을 유지하는 방법, 그리고 쿼터를 초과하는 계정의 비용을 생성자가 지불하는 방법.
  5. 자기거래: 운영자 자신, 직원, 파트너의 계정을 기증 RAM과 분리하는 방법.
  6. 책임성: 비정상적인 생성량에 대해 발생하는 경보, 생성자 자체의 중지 수단, 서명 키 탈취 시의 대응과 그 소요 시간.

각 프로듀서는 이 항목들에 대한 답변으로 신청서를 판단합니다.

생성자의 프로덕션 흐름이 giftacct를 호출하는 것을 보여 주는 Jungle 4 트랜잭션을 제시할 것을 권장합니다. 고정 커밋의 gift 컨트랙트 README가 통합 가이드이며, 실제 트랜잭션 예시를 담고 있습니다.

쿼터 증액이나 재승인에는 간단한 변경 요청을 사용하며, 이는 어디에나 게시할 수 있고 해당 msig의 첫 번째 액션에서 링크됩니다. 변경 요청에는 원래 신청서 링크, 현재 쿼터와 요청 쿼터, 승인 이후 사용량, 사유, 변경된 답변이 포함됩니다. 재승인의 경우 제거를 초래한 원인과 수정된 사항을 추가합니다. 쿼터 인하, 생성자 정지, 정지 해제에는 변경 요청이 필요하지 않습니다.

생성자 또는 프로그램의 중지

gift.vaulta@active의 두 하위 권한은 더 작은 규모의 프로듀서 그룹이 기증을 중지할 수 있게 하며, 각 권한은 eosio::linkauth로 해당 액션에 연결됩니다.

  • gift.vaulta@halt는 단일 권한 항목 eosio.prods@prod.major(21명 중 11명의 프로듀서)를 가지며, disable과 resume에 연결됩니다.
  • gift.vaulta@suspend는 단일 권한 항목 eosio.prods@prod.minor(21명 중 8명의 프로듀서)를 가지며, suspend에 연결됩니다.

두 권한 모두 prod.major와 prod.minor가 서명하는 방식인 eosio.msig를 통해 사용되므로, 중지를 실행하는 계정이 그 CPU와 NET 비용을 부담합니다. active(15/21)는 모든 액션을 실행할 수 있으며, enable, addcreator, rmcreator, setquota에는 active가 필요합니다.

  • 한 생성자 또는 전체의 정지: 프로듀서 8명이 어느 생성자든 정지시킬 수 있으며, 각 생성자에 대한 suspend를 담은 하나의 msig로 모든 생성자를 중지시킬 수 있습니다. msig가 승인을 모으는 동안, 키가 탈취된 생성자는 (days the msig takes + 1) × quota(msig 소요 일수에 1을 더한 값에 쿼터를 곱한 값)만큼 지출할 수 있습니다. 이미 열려 있는 윈도우가 쿼터 하나를 더하기 때문입니다. 기본 쿼터와 5일짜리 msig 기준으로 이는 1,572,864바이트(약 1.5 MiB)이며, 감수하기로 한 손실입니다. 생성자가 정지된 동안에도 enabled 플래그는 여전히 true로 읽히므로, 클라이언트는 해당 생성자의 기증이 실행되는지 판단하기 위해 그 생성자의 suspended 필드를 enabled와 함께 읽습니다.
  • 프로그램 중단: 프로듀서 11명이 프로그램 전체를 disable할 수 있습니다. enable로 재개하려면 15/21이 필요합니다.
  • 생성자 제거: 15/21의 rmcreator는 악의적이거나 활동을 중단한 생성자를 제거하며, setquota는 쿼터를 낮춥니다. 쿼터는 1,972바이트 미만으로 낮출 수 없으므로, 단일 생성자를 중지하는 수단은 suspend와 rmcreator입니다.
  • 생성자 키 탈취: 생성자가 자신의 키를 교체하면 공격자는 즉시 축출되고 등록은 그대로 유지됩니다.
  • 소수에 의한 중지: 신속한 중지 수단은 소수가 중지 상태를 유지할 수 있게도 합니다. 정지는 어느 프로듀서 8명이든 추가 suspend를 계속 승인하는 한 지속됩니다. 11명에 의한 resume은 다음 suspend가 실행될 때까지만 유효하며, 그 실행은 같은 블록에서 일어날 수도 있습니다. 또한 8명이 미리 승인해 둔 suspend 제안은 어느 계정이든 실행할 수 있으며, 그들이 승인한 뒤에 등록이 승인된 생성자를 대상으로 하는 경우에도 마찬가지입니다. 마찬가지로 resume 제안을 비축해 둔 프로듀서 11명은 모든 suspend를 되돌릴 수 있습니다. 두 그룹 간의 분쟁은 authorized_by를 active로 설정하여 suspend 권한의 authority 또는 링크를 변경함으로써 15/21로 해결됩니다(계정 권한 참고). 21명 중 어느 15명이든 그 8명 중 최소 2명을 포함하므로, 8명의 프로듀서가 함께 행동하면 그 변경도 막을 수 있으며, 그 경우 중지 유지는 투표자가 프로듀서 스케줄을 바꿀 때 끝납니다. 프로듀서 7명은 enable 승인을 보류함으로써 비활성화된 프로그램을 계속 꺼진 상태로 둘 수 있습니다. 프로듀서는 완전한 합의를 기다리지 않는 중지 수단을 얻는 대가로 이를 수용합니다.
  • 회수: 기증은 계정이 자체 RAM을 보유하게 된 후에만 ungiftram을 통해 계정을 떠날 수 있으며, ungiftram은 기증분 전체를 gift.vaulta로 반환합니다(알려진 제약 참고). 프로듀서는 eosio.wrap을 통한 15/21 ungiftram으로 반환을 강제할 수 있지만, 같은 msig가 먼저 해당 계정에 그 RAM을 제공해야 합니다. 최소 구성 계정에 대한 3,000바이트 기증의 경우 보충량은 1,596바이트이므로, 네트워크는 기증에 든 3,136바이트 중 1,540바이트를 돌려받고, 계정 보유자는 자신의 계정이 점유하는 1,596바이트를 소유하게 됩니다. 파밍된 계정에서 반환을 강제하면 파머에게 자신이 소유한 RAM으로 뒷받침되는 계정을 넘겨주게 되므로, 프로그램은 남용에 생성자 단계에서 대응하며, 중지가 적용되기 전에 기증되어 점유된 모든 바이트는 지출된 것으로 남습니다.

운영 중인 프로그램에는 msig가 필요하지 않습니다. 프로듀서는 생성자가 가입하거나, 더 많은 쿼터를 요청하거나, 부정행위를 할 때 조치하며, 승인마다 15/21 msig 한 건, 쿼터 증액마다 한 건이 필요합니다. 어느 프로듀서나 커뮤니티 구성원이든 기증 방식에 설명된 공개 기록에서 부정행위를 감시할 수 있습니다.

계정 권한

  • owner와 active는 모두 eosio.prods@active에 위임하며, 이는 15/21 BP 합의로 귀결됩니다. active는 gift.vaulta@eosio.code도 포함하므로 컨트랙트가 자체 권한으로 인라인 giftram을 전송할 수 있습니다. owner는 이를 포함하지 않으므로, 컨트랙트 코드는 결코 계정의 최상위 권한을 행사할 수 없습니다.
  • gift.vaulta는 일반적인 비특권 계정입니다. giftram은 기증자의 권한만 요구하며, 컨트랙트는 특권 호스트 함수를 호출하지 않습니다. 본 제안은 eosio.system의 변경을 요구하지 않습니다.
  • 생성자는 gift.vaulta에 대한 권한을 보유하지 않습니다. 생성자는 컨트랙트 레지스트리의 행이며, 관리자 액션을 통해 MSIG로 관리됩니다.
  • vp1deploy의 마지막 권한 단계는 eosio::limitauthchg(gift.vaulta, [owner, active], [])입니다. 링크는 일반 액션에 필요한 권한을 제한할 뿐 네이티브 권한 액션은 열어 두므로, 이 단계가 없으면 어느 하위 권한이든 자신의 authority를 변경하거나, 액션을 다시 연결하거나, gift.vaulta에 비용이 청구되는 추가 권한을 생성할 수 있습니다. 이 단계가 있으면 gift.vaulta에 대한 모든 updateauth, deleteauth, linkauth, unlinkauth는 owner 또는 active를 authorized_by로 지정하고 그 지정된 권한으로 승인되어야 하며, 그렇지 않으면 시스템 컨트랙트가 이를 거부합니다. active로 승인되었으나 owner를 지정한 변경은 실패합니다. 이로써 halt와 suspend는 연결된 액션으로 한정되며, 이는 eosio.wrap을 통한 것을 포함하여 이후의 모든 15/21 권한 변경에 적용됩니다.
  • 프로듀서는 gift.vaulta의 owner와 active authority를, 그리고 중지 수단도 옮기는 경우 halt와 suspend 권한을 변경하는 15/21 MSIG 한 건으로 프로그램의 거버넌스를 다른 기구에 넘길 수 있습니다. 컨트랙트는 gift.vaulta 자체의 권한만 확인하므로 변경이 필요하지 않습니다.

운영 규칙

프로듀서와 그들의 msig를 구성하는 사람은 다음 규칙을 지키며, 보안 검토는 이 규칙들을 해당 발견 사항을 해소하는 근거로 인용합니다.

  • gift.vaulta로의 모든 이전은 ramtransfer를 사용하며, gift.vaulta는 비관리 상태로 유지됩니다. 즉, 어떤 setacctram도 그 RAM 한도를 고정하지 않습니다. 한도를 고정하면 한도가 잔액을 따라가지 않게 됩니다.
  • disable, suspend, resume msig는 짧은 만료 기간을 가지며, 프로듀서는 gift.vaulta를 지정한 계류 중인 제안이 있는지 eosio.msig를 감시합니다.
  • enable msig를 실행하는 계정은 같은 트랜잭션에서 계류 중인 모든 disable 제안을 먼저 실행하여, 이를 되돌릴 제안이 남지 않게 합니다. 코드나 enabled 플래그를 설정하는 msig가 실행된 후에는 그 제안자가 플래그를 읽습니다.
  • gift.vaulta의 하위 권한은 새 이름으로 교체하여 폐기합니다. 하위 권한을 삭제하고 같은 이름으로 다시 생성하면, Spring이 권한을 이름으로 식별하므로 이전 권한 아래에서 승인된 모든 제안이 되살아납니다.
  • eosio.wrap을 통해 프로듀서의 승인을 무효화하면 해당 프로듀서가 체인 상에서 보유한 모든 승인이 무효화되므로, 프로듀서는 이를 체인 전체에 영향을 미치는 행위로 판단합니다.
  • 테이블 레이아웃을 변경하는 모든 컨트랙트 업그레이드는 binary_extension을 사용하거나 마이그레이션과 함께 배포되며, 모든 업그레이드 msig는 각 테이블에 대해 상태를 보존하는 액션으로 끝납니다. 프로그램이 켜져 있으면 disable 후 enable, 꺼져 있으면 enable 후 disable, 그리고 한 생성자에 대해 그 생성자의 현재 쿼터로 setquota를 실행합니다. 그러면 스키마 손상이 업그레이드 전체를 되돌립니다.
  • 기금이 소진에 가까워지면, 보충 msig를 모든 승인 msig보다 먼저 실행합니다.

기술 참고 사항

  • giftacct의 경로: giftacct는 최상위 액션 또는 인라인으로 전송될 수 있습니다. 생성자의 키로, 생성자가 승인한 eosio.msig 제안으로, creator@eosio.code를 보유한 생성자 컨트랙트로, 또는 eosio.wrap::exec를 통해 15/21의 프로듀서가 전송할 수 있습니다. 모든 경로는 지정된 생성자의 쿼터에서 차감하므로, 생성자는 자신의 권한으로 이루어진 모든 기증에 책임을 집니다. 승인된 msig 제안은 eosio.wrap 제안을 포함하여 어느 계정이든 실행할 수 있으며, 이를 실행하는 계정이 최상위 newaccount를 작성하고 신규 계정의 키를 선택합니다. 따라서 msig 경로를 사용하는 생성자는 마지막 승인, newaccount, 실행을 하나의 트랜잭션으로 보내거나, 접미사 소유자가 직접 newaccount에 서명하는 접미사 아래의 이름에만 기증합니다.
  • 인덱싱: 인덱서가 필요로 하는 모든 필드는 giftacct의 명시적 입력이며, giftacct는 어떤 경로로 전송되든 생성자를 지정합니다. 인덱서는 트랜잭션 자체의 액션뿐 아니라 인라인 트레이스에서도 giftacct를 읽으며, giftram이 인라인으로 전송되므로 RAM 잔액을 대조하려면 인라인 트레이스가 필요합니다. newaccount가 기록하는 creator는 서명자를 가리키며, 이는 쿼터로 비용을 낸 생성자와 다를 수 있으므로, 기금 지출은 giftacct에서 읽습니다.
  • 한 계정에 대한 두 번의 기증: 한 트랜잭션에서 같은 계정에 대한 두 번째 giftacct는 시스템 컨트랙트가 행을 하나만 유지함에도 136바이트를 다시 청구하므로, 추가 청구는 지출을 과대 계상할 뿐입니다.
  • 괴롭힘 불가: 생성 트랜잭션 외부의 누구도 신규 계정에 먼저 기증할 수 없으며, 프로그램은 기존 계정에 도달할 수 없습니다. gift.vaulta는 차단될 수 없습니다. 다른 주체가 gift.vaulta에 보내는 giftram은 잠긴 RAM을 추가할 뿐이며, 컨트랙트에는 알림 핸들러가 없으므로 수증자의 반환을 결코 거부하지 않습니다.
  • 검증: Spring 소스와 릴리스 v3.10.0의 시스템 컨트랙트를 기준으로 확인했습니다. 이 릴리스는 2025-07-15 Vaulta 전환 msig가 eosio에 배포한 것이며, 각 인용이 링크하는 커밋과 일치합니다. giftram은 기증자의 권한만 요구하며(delegate_bandwidth.cpp), 컨트랙트는 eosio.code를 통해 인라인으로 이를 충족합니다. 또한 giftram은 수령자가 존재하는지 확인하며, 이는 트랜잭션에서 앞서 실행되는 newaccount가 보장합니다. 신규 계정의 RAM은 트랜잭션 종료 시점에 확인되므로(Spring transaction_context::finalize), 인라인 기증이 계정의 사용량을 충당하며, 이는 newaccount와 buyrambytes의 조합이 의존하는 것과 동일한 메커니즘입니다. 1,400 무료 바이트는 시스템의 ram_gift_bytes입니다. 136바이트 행 오버헤드는 메인넷 트랜잭션 f2c6200c1add5ffc74837bcae1731ff5a66e259376eee6a4d4d7580f044a0b4c에서 확인되었으며, 이 트랜잭션에서 3,000바이트 기증은 기증자에게 정확히 136바이트를 청구했습니다.

공시

Greymass는 본 제안과 gift 컨트랙트를 작성했으며, Anchor와 Greymass 계정 포털의 계정 생성 서비스인 gm을 운영합니다. 2026-10-17 기준 Greymass는 상위 30위 프로듀서에 속하지 않으므로, 자사의 것을 포함하여 어떤 승인 msig에도 서명하지 않습니다. Greymass는 다음 단계에 설명된 대로 gm을 생성자로 신청할 계획입니다.

범위 경계

  • 기증은 계정 생성 시점에만 이루어지며 컨트랙트가 이를 강제하므로, 생성자는 기존 계정에 RAM을 추가로 지급할 수 없습니다.
  • 이 프로그램은 등록된 생성자에게 제공되며, 네트워크가 RAM을 부담합니다. 셀프서비스 유료 계정 생성은 new.vaulta(VP-0002)입니다.

알려진 제약

  • 계정당 단일 기증자: 시스템 컨트랙트는 한 번에 계정당 하나의 RAM 기증자만 허용합니다. 이 프로그램으로 생성된 계정은 네트워크의 기증분을 전액 반환하기 전까지 다른 주체의 giftram(예: 앱으로부터)을 받을 수 없습니다. 자체적으로 RAM을 구매하거나 ramtransfer로 받는 것에는 영향이 없습니다.
  • 전액 반환만 가능: ungiftram은 기증분 전체를 반환합니다. 수증자는 1,400바이트를 초과하는 사용량을 충당하는 자체 RAM과, 반환에 서명할 NET 및 CPU를 보유한 후에만 기증분을 반환할 수 있습니다.

미해결 질문

없음.

다음 단계

  1. Greymass가 vp1create를 제안합니다. 이 단계는 vp1create가 실행되면 완료됩니다.
  2. gift.vaulta가 존재하면 Greymass가 vp1deploy를 제안합니다. 이 단계는 vp1deploy가 enable을 마지막 액션으로 하여 실행되면 완료됩니다.
  3. Greymass가 gm의 생성자 신청서를 게시합니다. 그 승인 MSIG는 vp1deploy 이후에만 실행될 수 있습니다.
  4. 추가 생성자는 생성자 되기에 설명된 대로 신청하며, 각각 개별 15/21 MSIG로 승인됩니다.