부분 서명을 사용하면 여러 당사자가 서로 다른 시점에 또는 서로 다른 기기에서 동일한 트랜잭션에 서명할 수 있습니다. 코디네이터가 메시지를 생성하고, 필요한 각 서명자가 직렬화된 메시지 바이트에 정확히 서명하며, 코디네이터는 제출 전에 서명을 검증하고 병합합니다.
서명은 의도가 아니라 바이트를 승인합니다
수수료 지불자, 블록해시, 명령어 순서, 계정 목록 또는 모든 instruction data 중 하나라도 변경하면 다른 메시지가 생성되며, 이미 수집된 모든 서명이 무효화됩니다.
부분 서명 흐름
- 트랜잭션 명령어와 수수료를 지불할 주체에 합의합니다.
- 트랜잭션 유효 기간과 수수료 지불자를 설정합니다.
- 메시지를 한 번만 직렬화합니다. 해당 바이트는 변경할 수 없는 것으로 취급합니다.
- 메시지 바이트와 사람이 읽을 수 있는 요약을 각 서명자에게 전달합니다.
- 동일한 메시지 바이트에 대해 각 Ed25519 서명을 수집하고 검증합니다.
- 서명을 해당 필수 서명자 주소에 연결합니다.
- 필요한 모든 서명이 존재하고 유효한지 확인한 다음 제출합니다.
전체 예제
아래의 수수료 지불자와 SOL 전송자는 각자 독립적으로 서명합니다. 코디네이터는 두 서명을 모두 검증하고 병합한 뒤, 완성된 트랜잭션을 제출합니다.
이 예제는 코디네이터와 각 서명자 간의 경계를 명확히 보여 주기 위해 원시 Ed25519 서명을 사용합니다. 정확히 동일한 메시지 바이트에 서명하기만 하면, 지갑, 하드웨어 기기, 수탁 서비스 또는 오프라인 서명자가 로컬 keypair를 대신할 수 있습니다.
서명 전에 메시지 고정하기
모든 서명은 직렬화된 트랜잭션 메시지를 대상으로 합니다. 메시지에는 다음 항목이 모두 포함됩니다.
- 수수료 지불자
- 최근 블록해시 또는 durable nonce
- 모든 프로그램 및 계정 주소
- 계정의 서명자 및 쓰기 가능 권한
- 명령어 순서 및 instruction data
먼저 이러한 필드를 구성하고, 메시지를 한 번만 직렬화한 다음, 해당 바이트 배열을 모든 서명자에게 배포하세요. 각 서명 요청과 함께 메시지의 다이제스트를 저장해 두면, 코디네이터가 다른 메시지에 대해 반환된 서명을 거부할 수 있어 유용합니다.
메시지를 역직렬화하고 변경한 뒤에도 이전에 수집한 서명이 계속 유효하기를 기대해서는 안 됩니다. 만료된 블록해시를 교체하거나 수수료 지불자를 변경하는 것처럼 운영상의 변경으로 보이는 경우에도, 모든 서명자가 다시 서명해야 합니다.
수수료 지불자 조율하기
수수료 지불자는 항상 필수 서명자이며, 메시지를 고정하기 전에 선택해야 합니다. 해당 계정에 기본 수수료와 우선순위 수수료를 지불할 만큼 충분한 SOL이 있는지 확인하세요. 스폰서나 백엔드가 수수료를 지불하는 경우, 사용자의 서명을 수집하기 전에 해당 주소를 메시지에 포함해야 합니다. 스폰서를 나중에 추가하면 서명된 바이트가 변경됩니다.
코디네이터는 수신한 서명이 필수 서명자로 등록된 주소에 속하는지 검증해야 합니다. 임의의 공개 키를 허용하여 트랜잭션에 추가해서는 안 됩니다.
트랜잭션 유효 기간 관리
최근 블록해시 트랜잭션은 해당 블록해시가 validator의 최근 블록해시 큐에 남아 있는 동안에만 유효합니다. 다중 당사자 서명 흐름을 시작하기 전에, 모든 서명자가 lastValidBlockHeight 이전에 응답할 수 있는지 추정하세요.
블록해시가 만료되면 새 블록해시로 새 메시지를 생성하고 모든 서명을 다시 수집하세요. 시간이 더 오래 걸리거나 오프라인 서명자가 포함될 수 있는 워크플로에는 durable nonce를 사용하세요. durable nonce는 최근 블록해시 기간의 제약을 피할 수 있지만, 해당 nonce를 갱신하거나 다른 방식으로 소비하면 대기 중인 트랜잭션이 여전히 무효화됩니다.
제출 전 검증
반환된 모든 서명에 대해 다음을 수행합니다.
- 고정된 메시지 바이트와 예상 서명자의 공개 키를 기준으로 서명을 검증합니다.
- 트랜잭션 서명 배열에서 해당 서명자의 slot에 서명을 연결합니다.
- 조립된 트랜잭션에 모든 필수 서명자의 유효한 서명이 있는지 검증합니다.
- 메시지를 다시 구성하지 않고 직렬화된 트랜잭션을 제출합니다.
제출 후에는 서명된 메시지에 포함된 것과 동일한 유효 기간 정보를 사용하여 확인하세요. 확인 결과 블록해시가 만료되었거나 nonce가 소비된 것으로 보고되면, 수정된 트랜잭션으로 재시도하지 말고 서명 흐름을 처음부터 다시 시작하세요.
Is this page helpful?