계정 권한 시스템
개요
IOST의 계정 권한 시스템은 공개키-개인키 쌍 메커니즘을 기반으로 합니다. owner 키와 active 키를 설정함으로써 사용자는 여러 계정 시스템을 편리하게 관리할 수 있으며, 동시에 새로운 권한과 비밀 가중치를 자유롭게 설정할 수 있습니다. 이를 통해 다양한 맞춤형 관리 기능을 구현할 수 있습니다.
계정 시스템의 기본
IOST 계정은 ID와 권한으로 생성됩니다. 한 계정은 여러 권한을 가질 수 있으며, 최소한 owner와 active 권한을 가집니다. 각 권한에는 여러 항목(item)이 등록될 수 있고, 항목은 base58로 인코딩된 공개키이거나 다른 계정의 권한 쌍입니다.
권한 쌍은 account_name@permission_name 형식의 문자열로 표현할 수 있습니다.
각 항목은 일정한 가중치(weight)를 가지며, 각 권한은 그에 대응하는 임계값(threshold)을 가집니다. 트랜잭션 항목의 가중치 합이 임계값보다 크면 해당 트랜잭션이 그 권한을 가진 것으로 간주됩니다.
항목 소유권의 확인 방식은 다음과 같습니다. 항목이 공개키인 경우, 트랜잭션 서명에 해당 공개키에 대한 서명이 포함되어 있는지 확인합니다. 항목이 계정-권한 쌍인 경우, 해당 계정의 권한 항목을 재귀적으로 확인합니다.
일반적으로 스마트 컨트랙트는 권한 검증 시 자신의 계정 ID와 권한 ID를 제시합니다. 시스템은 트랜잭션의 서명을 확인하고 항목들의 가중치를 계산하여 임계값을 만족하면 트랜잭션을 검증하고, 그렇지 않으면 검증에 실패합니다.
active 권한은 owner 권한을 제외한 다른 모든 권한을 부여할 수 있습니다. owner 권한은 같은 권한들을 부여할 수 있을 뿐 아니라 owner와 active 권한 하위의 항목 변경도 허용합니다. 트랜잭션 제출 시에는 active 권한이 필요합니다.
권한은 그룹과 함께 동작할 수 있습니다. 그룹에 권한을 추가하고 그룹에 항목을 추가하면, 해당 항목들은 그룹의 모든 권한을 누리게 됩니다.
계정 시스템 사용법
스마트 컨트랙트에서는 간단한 API로 호출할 수 있습니다.
blockchain.requireAuth(id, permission_string)
이 호출은 boolean 값을 반환하므로 이를 바탕으로 작업 계속 여부를 결정하면 됩니다.
일반적으로 RAM과 토큰을 사용할 때는 먼저 사용자의 active 권한을 확인해야 합니다. 그렇지 않으면 스마트 컨트랙트가 예기치 않게 실패할 수 있습니다. permission_string에는 고유한 문자열을 골라서 권한 범위를 최소화하세요.
일반적으로 owner 권한을 요구해서는 안 됩니다. 사용자는 owner와 active 권한 자체를 수정할 때를 제외하고는 owner 키를 요구받아서는 안 됩니다.
트랜잭션 전송자에게 별도로 권한을 요구할 필요는 없습니다. 항상 active 권한을 가지고 있기 때문입니다.
사용자 수준에서는 서명을 제공해야만 사용자가 권한을 추가하는 것으로 보입니다. 두 개의 계정이 있다고 가정하고(모든 키의 가중치와 임계값이 1이라고 가정), 다음과 같은 구조라고 하겠습니다.
User0
├── Groups
│ └── grp0: key3
└── Permissions
├── owner: key0
├── active: key1
├── perm0: key2, grp0
├── perm1: User1@active, grp0
├── perm2(threshold = 2): key4, key5, grp0
├── perm3: key8
└── perm4(threshold = 2): User@perm3, key9
User1
└── Permissions
├── owner: key6
└── active: key7
RequireAuth 동작 예시
| 파라미터 | 서명 키 | 반환 | 비고 |
|---|---|---|---|
| User0, perm0 | key2 | true | 공개키에 대한 서명이 제공되면 권한이 부여됨 |
| User0, perm0 | key3 | true | 그룹 서명이 제공되면 권한이 부여됨 |
| User0, perm0 | key1 | true | active 키가 제공되면 (owner를 제외하고) 모든 권한이 부여됨 |
| User0, perm1 | key7 | true | key7은 User1@active 권한을 제공하므로 perm1이 부여됨 |
| User0, owner | key1 | false | active는 owner 권한을 부여하지 않음 |
| User0, active | key0 | true | owner는 모든 권한을 부여함 |
| User0, perm2 | key4 | false | 서명이 임계값에 도달하지 못함 |
| User0, perm2 | key4, key5 | true | 서명이 임계값에 도달함 |
| User0, perm2 | key3 | true | 권한 그룹은 임계값을 계산·검사하지 않음 |
| User0, perm2 | key1 | true | active는 임계값을 검사하지 않음 |
| User0, perm4 | key8 | false | 권한 그룹의 가중치 계산 시 구현 가능 |
계정 생성과 관리
계정 관리는 auth.iost 컨트랙트를 기반으로 합니다. ABI는 다음과 같습니다.
{
"lang": "javascript",
"version": "1.0.0",
"abi": [
{
"name": "signUp", // 계정 생성
"args": ["string", "string", "string"] // 사용자명, ownerKey ID, activeKey ID
},
{
"name": "addPermission", // 권한 추가
"args": ["string", "string", "number"] // 사용자명, 권한 이름, 임계값
},
{
"name": "dropPermission", // 권한 삭제
"args": ["string", "string"] // 사용자명, 권한 이름
},
{
"name": "assignPermission", // 항목에 권한 할당
"args": ["string", "string", "string","number"] // 사용자명, 권한, 공개키 ID 또는 account_name@permission_name, 가중치
},
{
"name": "revokePermission", // 권한 회수
"args": ["string", "string", "string"] // 사용자명, 권한, 공개키 ID 또는 account_name@permission_name
},
{
"name": "addGroup", // 권한 그룹 추가
"args": ["string", "string"] // 사용자명, 그룹 이름
},
{
"name": "dropGroup", // 그룹 삭제
"args": ["string", "string"] // 사용자명, 그룹 이름
},
{
"name": "assignGroup", // 그룹에 항목 할당
"args": ["string", "string", "string", "number"] // 사용자명, 그룹 이름, 공개키 ID 또는 account_name@permission_name, 가중치
},
{
"name": "revokeGroup", // 그룹에서 항목 회수
"args": ["string", "string", "string"] // 사용자명, 그룹 이름, 공개키 ID 또는 account_name@permission_name
},
{
"name": "assignPermissionToGroup", // 그룹에 권한 할당
"args": ["string", "string", "string"] // 사용자명, 권한 이름, 그룹 이름
},
{
"name": "revokePermissionInGroup", // 그룹에서 권한 회수
"args": ["string", "string", "string"] // 사용자명, 권한 이름, 그룹 이름
}
]
}
계정 이름은 [a-z0-9_] 문자만 유효하며, 길이는 511자입니다. 권한 이름과 그룹 이름은 32자입니다.[a-zA-Z0-9_]만 유효하며 길이는 1
새 계정은 최소 10 IOST의 가스 스테이킹이 필요하며, signUp 메서드는 새 계정에 대해 이 스테이킹을 자동으로 수행합니다.
따라서 새 계정을 만들려면 10 IOST와 0 바이트 RAM이 필요합니다.