이 예제에서 채널의 공개 키는 결제자 마스터 키 쌍의 공개 키입니다. 이는 완벽하게 안전하고 유효합니다. 결제자만 해당 키 쌍의 공개키와 비밀키를 알고 있다면 다른 키 쌍을 사용하는 것도 완벽하게 안전하고 유효합니다.
또한 트랜잭션을 전송할 rippled 서버가 필요합니다. 이 튜토리얼의 예시에서는 rippled 서버가 테스트 머신(로컬 호스트)에서 포트 5005의 암호화되지 않은 JSON-RPC API 엔드포인트로 실행되고 있다고 가정합니다.
실제 XRP를 전송하지 않고 테스트하려면 testnet XRP와 함께 XRP Ledger testnet 주소를 사용할 수 있습니다. testnet을 사용하는 경우 http://localhost:5005/ 대신 https://api.altnet.rippletest.net:51234 에 연결하여 testnet 서버의 JSON-RPC API를 사용할 수 있습니다.
결제 채널에는 원하는 금액의 XRP를 사용할 수 있습니다. 이 튜토리얼의 예시 값은 결제 채널에 최소 1일 동안 100RP(100000000드롭)를 따로 설정했습니다.
흐름 다이어그램(Flow Diagram)
다음 다이어그램은 결제 채널의 수명 주기를 요약한 것입니다:
이 다이어그램의 번호가 매겨진 단계를 이 튜토리얼의 단계와 일치시킬 수 있습니다.
결제자: 채널 생성
수취인: 채널 확인
지급인 청구 서명
수취인: 수취인에게 청구 보내기
수취인: 청구 확인
수취인 상품 또는 서비스 제공
원하는 대로 3~6단계를 반복합니다.
수취인: 클레임 상환
지급인: 채널 폐쇄 요청
지급인(또는 다른 사람): 만료된 채널 닫기
1. 결제자가 특정 수신자에 대한 결제 채널을 생성합니다.(The payer creates a payment channel to a particular recipient.)
이것이 PaymentChannelCreate 트랜잭션입니다. 이 프로세스의 일부로 결제자는 채널의 청구에 대한 보증에 영향을 주는 만료 시간 및 결제 지연과 같은 채널의 특정 세부 정보를 설정합니다. 또한 지급자는 채널에 대한 청구를 확인하는 데 사용할 공개 키도 설정합니다.
Tip:
'정산 지연'은 정산을 지연시키지 않으며, ledger버전이 닫히는 시간(3~5초)만큼 빠르게 정산이 이루어질 수 있습니다. '정산 지연'은 수취인이 정산을 완료할 수 있도록 채널을 닫을 때 강제적으로 지연되는 것입니다.
다음 예시는 JSON-RPC API로 로컬 rippled 서버에 제출하여 결제 채널을 생성하는 예시입니다. 결제 채널은 예시 지급인(rN7n7...)으로부터 예시 수취인(rf1Bi...)에게 1일의 결제 지연을 두고 100개의 XRP를 할당합니다. 공개 키는 예시 지급인의 마스터 공개 키(16진수)입니다.
Note:
결제 채널은 결제자의 소유자 reserve에 하나의 객체로 계산됩니다. 소유자는 결제 채널에 할당된 XRP를 차감한 후에도 준비금을 충족할 수 있는 최소한의 XRP를 보유해야 합니다.
요청:
POST http://localhost:5005/Content-Type: application/json{"method":"submit","params": [{"secret":"s████████████████████████████","tx_json": {"Account":"rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH","TransactionType":"PaymentChannelCreate","Amount":"100000000","Destination":"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn","SettleDelay":86400,"PublicKey":"023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6","DestinationTag":20170428 },"fee_mult_max":1000 }]}```jsonResponse:```json200 OK{"result": {"engine_result":"tesSUCCESS","engine_result_code":0,"engine_result_message":"The transaction was applied. Only final in a validated ledger.", ..."tx_json": { ..."TransactionType":"PaymentChannelCreate","hash":"3F93C482C0BC2A1387D9E67DF60BECBB76CC2160AE98522C77AF0074D548F67D" } }}
제출 요청에 대한 즉각적인 응답에는 트랜잭션의 식별 해시값이 포함된 잠정 결과가 포함됩니다. 결제자는 검증된 ledger에서 트랜잭션의 최종 결과를 확인하고 메타데이터에서 채널 ID를 가져와야 합니다. 이 작업은 tx 명령으로 수행할 수 있습니다:
요청:
POST http://localhost:5005/Content-Type: application/json{"method":"tx","params": [{"transaction":"3F93C482C0BC2A1387D9E67DF60BECBB76CC2160AE98522C77AF0074D548F67D" }]}
응답이 "validated":true인지 확인하여 데이터가 유효성 검증된 ledger에서 가져온 것임을 표시합니다. (유효성이 검증된 ledger 버전에 나타나는 경우에만 tesSUCCESS 결과가 최종적입니다.)
트랜잭션 메타 필드의 AffectedNodes 배열에서 LedgerEntryType이 PayChannel인 CreatedNode 객체를 찾습니다. CreatedNode 객체의 LedgerIndex 필드는 채널 ID를 나타냅니다. (위 예제에서는 "5DB0..."로 시작하는 16진수 문자열입니다.) 채널 ID는 나중에 청에 서명하는 데 필요합니다. PayChannel ledger 객체 유형에 대한 자세한 내용은 PayChannel ledger 객체를 참조하세요.
2. 수취인이 결제 채널의 세부 정보를 확인합니다.(The payee checks specifics of the payment channel.)
다음 예제에서와 같이 채널의 수취인을 사용하여 account_channels 메소드로 결제 채널을 조회할 수 있습니다(JSON-RPC API 사용):
요청:
POST http://localhost:5005/Content-Type: application/json{"method":"account_channels","params": [{"account":"rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH","destination_account":"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn","ledger_index":"validated" }]}
수취인은 결제 채널의 매개변수가 다음 사항을 모두 포함하여 특정 사용 사례에 적합한지 확인해야 합니다:
destination_account 필드에 수취인의 주소가 올바른지 확인합니다.
수취인이 미결제 청구를 상환할 수 있는 충분한 시간을 제공하는 결제 지연 시간(초)이 settle_delay 필드에 입력되어 있는지 확인합니다.
cancel_after(변경 불가능한 만료) 및 expiration(변경 가능한 만료) 필드가 있는 경우 너무 이르지 않은지 확인합니다. 수취인은 이 시간을 기록해 두었다가 그 전에 청구를 상환할 수 있도록 해야 합니다.
공개 키와 채널 ID 필드를 기록해 두세요. 나중에 클레임을 확인하고 상환하는 데 필요합니다.
(선택 사항) destination_tag 필드가 존재하고 원하는 데스티네이션태그가 있는지 확인합니다.
동일한 두 당사자 간에 여러 채널이 있을 수 있으므로 수취인이 올바른 채널의 자격을 확인하는 것이 중요합니다. 혼동할 가능성이 있는 경우, 수취인은 사용할 채널의 채널 ID(channel_id)를 명확히 해야 합니다.
3. 결제자가 채널에서 XRP에 대해 하나 이상의 서명된 청구를 생성합니다.(The payer creates one or more signed claims for the XRP in the channel.)
이러한 청구 금액은 결제자가 지불하고자 하는 특정 상품이나 서비스에 따라 다릅니다.
각 청구는 누적 금액에 대한 청구여야 합니다. 즉, 각각 10XRP로 두 개의 상품을 구매하려면 첫 번째 청구 금액은 10XRP이고 두 번째 청구의 금액은 20XRP여야 합니다. 청구 금액은 채널에 할당된 총 XRP 금액을 초과할 수 없습니다. (PaymentChannelFund 트랜잭션은 채널에 할당된 총 XRP 금액을 늘릴 수 있습니다.)
channel_authorize 메소드로 클레임을 생성할 수 있습니다. 다음 예시는 채널에서 1 XRP를 승인하는 예시입니다:
요청:
POST http://localhost:5005/Content-Type: application/json{"method":"channel_authorize","params": [{"channel_id":"5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3","secret":"s████████████████████████████","amount":"1000000" }]}
4. 지급인이 수취인에게 상품이나 서비스에 대한 대금으로 청구를 보냅니다.(The payer sends a claim to the payee as payment for goods or services)
이 통신은 지급인과 수취인이 동의할 수 있는 모든 통신 시스템에서 "ledger 외부"에서 이루어집니다. 이를 위해 보안 통신을 사용해야 하지만 반드시 보안 통신을 사용해야 하는 것은 아닙니다. 채널의 지급인 또는 수취인만 해당 채널에 대한 청구를를 상환할 수 있습니다.
304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064(Note: this long string has been broken to fit on one line.)
수취인은 채널과 연결된 공개 키를 알고 있어야 하며, 이 공개 키는 채널의 수명이 다할 때까지 동일합니다.
5. 수취인이 청구를 확인합니다.(The payee verifies the claims)
channel_verify 메소드를 사용하여 청구를 확인할 수 있습니다. 수취인은 청구 금액이 제공된 상품 및 서비스의 총 가격보다 크거나 같은지 확인해야 합니다. (금액은 누적 금액이므로 지금까지 구매한 모든 상품 및 서비스의 총 가격입니다.)
JSON-RPC API로 channel_verify를 사용하는 예시입니다:
요청:
POST http://localhost:5005/Content-Type: application/json{"method":"channel_verify","params": [{"channel_id":"5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3","signature":"304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064","public_key":"aB44YfzW24VDEJQ2UuLPV2PvqcPCSoLnL7y5M1EzhdW4LnK5xMS3","amount":"1000000" }]}
응답에 "signature_verified": true가 표시되면 청구 서명이 진짜인 것입니다. 또한 수취인은 채널에 클레임을 처리할 수 있는 충분한 XRP가 있는지 확인해야 합니다. 이를 위해 수취인은 account_channels 메소드를 사용하여 결제 채널의 가장 최근 유효성이 확인된 상태를 확인합니다.
요청:
POST http://localhost:5005/Content-Type: application/json{"method":"account_channels","params": [{"account":"rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH","destination_account":"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn","ledger_index":"validated" }]}
8. 준비가 되면 수취인이 승인된 금액에 대한 청구를 상환합니다.(When ready, the payee redeems a claim for the authorized amount)
수취인이 채널에서 최종적으로 XRP를 받는 시점입니다.
잔액, 금액, 서명, 공개키 필드가 제공된 PaymentChannelClaim 트랜잭션입니다. 청구 값은 누적되므로 수취인은 가장 큰(가장 최근의) 청구만 상환하면 전체 금액을 받을 수 있습니다. 수취인이 승인된 전체 금액에 대해 클레임을 상환할 필요는 없습니다.
수취인은 원하는 경우 이 작업을 여러 번 수행하여 비즈니스를 계속 진행하면서 부분적으로 정산할 수 있습니다.
채널에서 XRP를 청구하는 예시입니다:
요청:
POST http://localhost:5005/Content-Type: application/json{"method":"submit","params": [{"secret":"s████████████████████████████","tx_json": {"Account":"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn","TransactionType":"PaymentChannelClaim","Amount":"1000000","Balance":"1000000","Channel":"5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3","PublicKey":"023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6","Signature":"304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064" },"fee_mult_max":1000 }]}
응답:
200 OK{"result": {"engine_result":"tesSUCCESS","engine_result_code":0,"engine_result_message":"The transaction was applied. Only final in a validated ledger.","status":"success", "tx_blob": "12000F2280000000240000017450165DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB36140000000000F42406240000000000F424068400000000000000A7121023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6732103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB7447304502210096B933BC24DA77D8C4057B4780B282BA66C668DFE1ACF4EEC063AD6661725797022037C8823669CE91AACA8CC754C9F041359F85B0B32384AEA141EBC3603798A24C7646304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF5029006481144B4E9C06F24296074F7BC48F92A97916C6DC5EA9",
"tx_json": {"Account":"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn","Amount":"1000000","Balance":"1000000","Channel":"5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3","Fee":"10","Flags":2147483648,"PublicKey":"023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6","Sequence":372,"Signature":"304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064","SigningPubKey":"03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB","TransactionType":"PaymentChannelClaim","TxnSignature":"304502210096B933BC24DA77D8C4057B4780B282BA66C668DFE1ACF4EEC063AD6661725797022037C8823669CE91AACA8CC754C9F041359F85B0B32384AEA141EBC3603798A24C","hash":"C9FE08FC88CF76C3B06622ADAA47AE99CABB3380E4D195E7751274CFD87910EB" } }}
수취인은 검증된 ledger에서 이 거래가 성공했음을 확인해야 합니다. 자세한 내용은 신뢰할 수 있는 트랜잭션 제출을 참조하세요.
9. 송금인과 수취인이 거래를 완료하면 송금인은 채널 폐쇄를 요청합니다.(When the payer and payee are done doing business, the payer requests for the channel to be closed)
이는 tfClose 플래그가 설정된 PaymentChannelClaim 트랜잭션 또는 Expiration 필드가 설정된 PaymentChannelFund 트랜잭션입니다. (흐름 다이어그램의 9a).
결제자가 채널 폐쇄를 요청할 때 채널에 XRP가 남아 있지 않으면 채널이 즉시 폐쇄됩니다.
채널에 XRP가 남아 있는 경우, 채널 폐쇄 요청은 수취인에게 미결제 청구를 즉시 상환하라는 최종 경고로 작용합니다. 수취인은 채널이 닫히기 전까지 결제 지연 시간만큼의 시간을 가질 수 있습니다. 정확한 시간(초)은 ledger의 마감 시간에 따라 약간씩 달라집니다.
트랜잭션이 검증된 원장에 포함된 후, 양쪽 당사자는 account_channels 메소드를 사용하여 채널의 현재 예정된 만료를 조회할 수 있습니다. 반드시 "ledger_index": "validated"를 지정하여 최신 유효성이 검증된 ledger 버전에서 데이터를 가져와야 합니다.
이 예시에서 만료 값 547073182는 Ripple 에포크 이후 초 단위로 2017-05-02T20:46:22Z에 매핑되므로, 해당 시간까지 상환되지 않은 청구는 더 이상 유효하지 않습니다.
10. 만료된 채널은 누구나 폐쇄할 수 있습니다.(Anyone can close the expired channel)
결제 지연 시간이 지나거나 채널이 예정된 만료 시간에 도달하면 채널이 만료됩니다. 채널에 영향을 줄 수 있는 추가 트랜잭션은 채널만 닫을 수 있으며, 미청구 XRP는 지급자에게 반환됩니다.
채널은 만료된 상태로 ledger에 무기한 남아있을 수 있습니다. ledger는 랜잭션의 결과 외에는 변경할 수 없기 때문에 만료된 채널을 닫으려면 누군가 트랜잭션을 보내야 합니다. 채널이 ledger에 남아 있는 한, 채널은 소유자 reserve의 목적상 결제자가 소유한 객체로 간주됩니다.
Ripple은 결제자가 이를 위해 tfClose 플래그가 포함된 두 번째 PaymentChannelClaim 트랜잭션을 전송할 것을 권장합니다. 그러나 결제 채널에 관여하지 않은 계정이라도 다른 계정으로 인해 만료된 채널이 닫힐 수 있습니다.
트랜잭션을 제출하는 명령은 채널 만료를 요청하는 이전 예제와 동일합니다. (그러나 자동으로 채워지는 시퀀스 번호, 서명 및 식별 해시는 고유합니다.)