Las carteras y cuentas con múltiples firmas permiten que varias personas accedan a sus activos en función de parámetros específicos. Una billetera multi-firma podría contener el tesoro comunal de una organización autónoma descentralizada (DAO) u otro grupo, por ejemplo. La billetera podría requerir que el 25 por ciento de los miembros firmen una transacción antes de que se pueda mover cualquier activo.

A diferencia de las simples billeteras de un solo propietario, las billeteras multifirma abren un mundo de usos posibles, permitiéndole crear componentes de juegos y aplicaciones comerciales, como dos ejemplos, que solo pueden ser desbloqueadas por varios usuarios. Requerir un quórum de usuarios o establecer otras condiciones de desbloqueo mantiene los activos digitales a salvo de un solo usuario deshonesto que asalte una cuenta.

Un contrato inteligente multi-firma, escrito en Move, sirve como componente principal para este tipo de aplicación en Sui. El contrato inteligente multifirma presentado en este artículo verifica las direcciones multifirma y admite diferentes combinaciones de claves, como 2 de 3 o M de N, donde M y N son parámetros definidos por el usuario.

Crear y usar el contrato de verificación multifirma en Move

Una dirección multifirma es un tipo especial de dirección que requiere múltiples firmas para autorizar una transacción. Un contrato inteligente de verificación multifirma deriva una dirección multifirma a partir de un conjunto de claves públicas, pesos y un umbral, y la compara con una dirección esperada.

Las direcciones multifirma requieren varias firmas para autorizar una transacción. A menudo se utilizan para mejorar la seguridad de los fondos distribuyendo el control entre múltiples partes. Por ejemplo, una dirección multifirma 2 de 3 requiere que al menos dos de cada tres firmantes aprueben una transacción. Las direcciones multifirma también se pueden utilizar con fines de gobierno, custodia o respaldo.

El contrato inteligente multifirma realiza tres funciones. Deriva direcciones multifirma, las verifica y puede verificar la dirección multifirma del remitente.

Derivar direcciones multifirma

El módulo multifirma define el

deriva_multisig_address_quiet

que toma tres parámetros: pks, pesos y umbral.

El

paquetes

El parámetro es un vector de vectores de bytes, que representa las claves públicas de los firmantes.

El

pesas

El parámetro es un vector de bytes que representa los pesos de cada firmante.

El

límite

El parámetro es un entero sin signo de 16 bits, que representa la suma mínima de pesos necesarios para ejecutar una transacción desde la dirección de firma múltiple.

La función devuelve una dirección, que es la dirección de firma múltiple derivada.

diversión pública deriva_multisig_address_quiet(         pks: vector<vector<u8>>,         pesos: vector<u8>,         umbral: u16,     ): dirección {

La función realiza los siguientes pasos:

Define una variable,

multiSigFlag

, de tipo entero sin signo de 8 bits y le asigna el valor 0x03, que es el indicador para direcciones de firma múltiple.

dejar multiSigFlag = 0x03;

Crea un vector vacío de bytes llamado

datos_hash

, que almacenará los datos que se van a aplicar hash.

let hash_data = vector<u8>[];

Obtiene las longitudes de la

paquetes

y pondera los vectores y comprueba que sean iguales. En caso contrario, aborta la ejecución con un código de error: ELengthsOfPksAndWeightsAreNotEqual.

let pks_len = pgs.length(); let pesos_len = pesos.longitud(); afirmar!(pks_len == pesos_len, ELengthsOfPksAndWeightsAreNotEqual);

Inicializa una variable,

suma

, de tipo entero sin signo de 16 bits y le asigna el valor 0. Luego recorre el vector de pesos y suma los valores de cada elemento a la suma. Luego verifica que el umbral sea positivo y no mayor que la suma. En caso contrario, aborta la ejecución con un código de error: EThresholdIsPositiveAndNotGreaterThanTheSumOfWeights.

sea ​​mut suma = 0; sea ​​mut i = 0; while (i < pesos_len) {             let w = pesos[i] como u16; suma = suma + w; yo = yo + 1; }; afirmar!(umbral > 0 && umbral <= suma, EThresholdIsPositiveAndNotGreaterThanTheSumOfWeights);

Empuja el

multiSigFlag

al vector hash_data. Luego serializa el umbral usando la función bcs::to_bytes y agrega el resultado al vector hash_data.

hash_data.push_back(multiSigFlag); let umbral_bytes: vector<u8> = bcs::to_bytes(&umbral); hash_data.append(umbral_bytes);

Recorre el

paquetes

y pondera los vectores y agrega los elementos de cada par al vector hash_data.

sea ​​mut i = 0; mientras (i < pks_len) { hash_data.append(pks[i]); hash_data.push_back(pesos[i]); yo = yo + 1; };

Hash el

datos_hash

vector usando la función blake2b256 y convierte el resultado en una dirección usando la función dirección::from_bytes. Luego asigna la dirección a una variable, ms_address, y la devuelve.

let ms_address = dirección::from_bytes(blake2b256(&hash_data)); dirección_ms     }

Deriva una dirección multifirma y devuelve la dirección multifirma.

Verificación de direcciones multifirma

El

multigrado

El módulo también define check_multisig_address_eq, que verifica si la dirección multifirma creada coincide con la dirección esperada. Como mencionamos anteriormente, una dirección multifirma es un tipo especial de dirección que requiere múltiples firmas para autorizar una transacción. Una dirección multifirma se define mediante un conjunto de claves públicas, pesos y un umbral.

La función

check_multisig_address_eq

toma cuatro parámetros: paquetes, pesos, umbral y dirección_esperada. Los primeros tres parámetros son los mismos que usamos en la función anterior, derive_multisig_address_quiet. El último parámetro, dirección_esperada, es un valor de dirección que queremos comparar con la dirección multifirma.

entrada pública divertida check_multisig_address_eq(         pks: vector<vector<u8>>,         pesos: vector<u8>,         umbral: u16,         dirección_esperada: dirección,     ): bool {

La función primero llama a la función,

deriva_multisig_address_quiet

, que crea una dirección de firma múltiple a partir de las claves públicas, los pesos y el umbral dados. Esta función utiliza un algoritmo basado en hash para combinar las claves públicas y el umbral en un valor de 16 bytes, que luego se convierte en una dirección.

let ms_address = derive_multisig_address_quiet(pks, pesos, umbral);

Luego, la función compara la dirección multifirma con la dirección esperada y devuelve verdadero si las direcciones son iguales y falso en caso contrario.

retorno (dirección_ms == dirección_esperada)

La función

check_multisig_address_eq

se puede utilizar para verificar que una dirección multifirma sea correcta y coincida con el valor esperado. Esto puede resultar útil para fines de prueba, depuración o auditoría. Por ejemplo, se podría utilizar esta función para comprobar que una dirección multifirma sea coherente con las claves públicas y el umbral acordado por los firmantes.

Comprobación de la dirección multifirma del remitente

Finalmente, el

multigrado

El módulo también define check_if_sender_is_multisig_address, que verifica si el remitente es la misma dirección multifirma que se deriva de los paquetes, pesos y umbrales proporcionados.

El

check_if_sender_is_multisig_address

toma cuatro parámetros: pks, pesos, umbral y ctx. Los primeros tres parámetros definen el esquema de dirección multifirma, mientras que el último parámetro proporciona el contexto de la transacción.

El

paquetes

El parámetro es un vector de vectores de bytes, que representa las claves públicas de los firmantes.

El

pesas

El parámetro es un vector de bytes que representa los pesos de cada firmante.

El

límite

El parámetro es un entero sin signo de 16 bits, que representa la suma mínima de pesos necesarios para ejecutar una transacción desde la dirección multifirma.

Finalmente, el

ctx

es una referencia mutable al TxContext, que contiene información sobre la transacción actual, como el remitente.

public fun check_if_sender_is_multisig_address(         pks: vector<vector<u8>>,         pesos: vector<u8>,         umbral: u16,         ctx: &mut TxContext     ): bool {

El

check_if_sender_is_multisig_address

La función llama a la función check_multisig_address_eq, que compara la dirección multifirma con la dirección del remitente.

check_multisig_address_eq(pks, pesos, umbral, ctx.sender())             }

La función

check_multisig_address_eq

Devuelve verdadero si la dirección del remitente coincide con el esquema de dirección multifirma y falso en caso contrario.

Comience con la firma múltiple

Las direcciones de firma múltiple son útiles para escenarios en los que es necesario mejorar la seguridad, la responsabilidad o la colaboración entre varias partes. Dados los valiosos activos digitales almacenados en Sui, una dirección multifirma puede ayudar a mantener esos activos seguros.

El contrato inteligente descrito en este artículo puede ayudarle a comenzar a crear aplicaciones diseñadas para la colaboración y la custodia compartida de activos. Como recurso adicional, puede consultar el código fuente y la documentación de este proyecto en GitHub.