@btc-vision/btc-runtime
Version:
Bitcoin Smart Contract Runtime
64 lines (50 loc) • 1.83 kB
text/typescript
import { BytesWriter } from '../buffer/BytesWriter';
import { Blockchain } from '../env';
import { encodePointerUnknownLength } from '../math/abi';
export class KeyMerger<K extends string, K2 extends string, V extends Uint8Array> {
public parentKey: K;
public pointer: u16;
constructor(parent: K, pointer: u16) {
this.pointer = pointer;
this.parentKey = parent;
}
public set(key2: K2, value: V): this {
const mergedKey: string = this.mergeKey(key2);
const keyHash: Uint8Array = this.encodePointer(mergedKey);
Blockchain.setStorageAt(keyHash, value);
return this;
}
public get(key: K): Uint8Array {
const mergedKey: string = this.mergeKey(key);
return Blockchain.getStorageAt(this.encodePointer(mergedKey));
}
public has(key: K): bool {
const mergedKey: string = this.mergeKey(key);
return Blockchain.hasStorageAt(this.encodePointer(mergedKey));
}
public delete(_key: K): bool {
throw new Error('Method not implemented.');
}
public clear(): void {
throw new Error('Clear method not implemented.');
}
/**
* Merges the parentKey and the provided key by prefixing each with its length.
* This avoids collisions such as:
* parentKey = "abc", key = "def" => "3:abc3:def"
* parentKey = "ab", key = "cdef" => "2:ab4:cdef"
*/
private mergeKey(key: string): string {
return `${this.parentKey.length}:${this.parentKey}${key.length}:${key}`;
}
private encodePointer(key: string): Uint8Array {
const writer = new BytesWriter(key.length);
writer.writeString(key);
return encodePointerUnknownLength(this.pointer, writer.getBuffer());
}
}